/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * nihongo
 * Copyright (C) Massimiliano Maniscalco 2011, 2012 <massi.neptune@yahoo.com>
 * 
 * nihongo is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * nihongo is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "controller.h"
#include "parser_xml.h"
#include "stringa_in_esempio.h"
#include "stringa_in_parola.h"
#include "stringa_contiene_parola.h"
#include "stringa_contiene_kanji.h"


void Controller::
load_data ( const Glib::ustring &filename )
{
	Glib::RefPtr<Gio::File> dataFile = Gio::File::create_for_path ( filename );
	if ( dataFile->query_exists () )
	{
		bool result;
		_mainStatus->push ( "Caricamento dati...", _stsItemDiskId );
		result = load_items_from_xml_file ( filename );
		if ( result )
		{
			_testCtrl->parole ( _parole );
			_testCtrl->kanji ( _kanji );
			_testCtrl->lezioni ( _lezioni );
		}
		else
			_mainStatus->push ( Glib::ustring ( "Errore di caricamento dei dati!" ), _stsItemDiskId );
	}
}

bool Controller::
save_data ( const Glib::ustring &filename )
{
	Glib::ustring _messaggio ( "Salvato: " );
	int np = 0;
	int nk = 0;
	int ne = 0;
	int nl = 0;
	bool result = true;
	ofstream outfile ( filename.c_str(), ios_base::out );
	if ( !outfile )
		cerr << "saveData:: unable to open file \"" << filename << "\"" << endl;
	else
	{
		outfile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
		outfile << "<nihongo>\n";
		np = save_items_to_xml_file ( *_parole, &outfile );
		if ( np != _parole->size() )
			result = false;
		else
		{
			if ( np == 1 )
				_messaggio.append ( Glib::ustring::compose("%1 parola", Glib::ustring::format(np) ) );
			else
				_messaggio.append ( Glib::ustring::compose("%1 parole", Glib::ustring::format(np) ) );
		}
		_messaggio.append ( ", " );
		nk = save_items_to_xml_file ( *_kanji, &outfile );
		if ( nk != _kanji->size() )
			result = false;
		else
			_messaggio.append ( Glib::ustring::compose("%1 kanji", Glib::ustring::format(nk) ) );
		_messaggio.append ( ", " );
		ne = save_items_to_xml_file ( *_esempi, &outfile );
		if ( ne != _esempi->size() )
			result = false;
		else
		{
			if ( ne == 1 )
				_messaggio.append ( Glib::ustring::compose("%1 esempio", Glib::ustring::format(ne) ) );
			else
				_messaggio.append ( Glib::ustring::compose("%1 esempi", Glib::ustring::format(ne) ) );
		}
		_messaggio.append ( ", " );
		nl = save_items_to_xml_file ( *_lezioni, &outfile );
		if ( nl != _lezioni->size() )
			result = false;
		else
		{
			if ( nl == 1 )
				_messaggio.append ( Glib::ustring::compose("%1 lezione", Glib::ustring::format(nl) ) );
			else
				_messaggio.append ( Glib::ustring::compose("%1 lezioni", Glib::ustring::format(nl) ) );
		}
		outfile << "</nihongo>";
		if ( outfile.fail() )
			result = false;
		outfile.close();
	}
	_mainStatus->pop ( _stsItemDiskId );
	if ( result )
	{
		_mainStatus->push ( _messaggio, _stsItemDiskId );
		_shouldSave = false;
	}
	else
		_mainStatus->push ( Glib::ustring ( "Errore di salvataggio dei dati!" ), _stsItemDiskId );
	return result;
}

bool Controller::
load_items_from_xml_file ( const Glib::ustring &filename )
{
	bool result = false;
	if ( filename != Glib::ustring ( "" ) )
	{
		sigc::connection _parserXmlAttributeFound;
		sigc::connection _parserXmlParolaImported;
		sigc::connection _parserXmlKanjiImported;
		sigc::connection _parserXmlEsempioImported;
		sigc::connection _parserXmlLezioneImported;
		sigc::connection _parserXmlImportEnd;
		// Parse the entire document in one go:
#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
		try
		{
#endif //LIBXMLCPP_EXCEPTIONS_ENABLED 
			ParserXML parser;
			parser.set_substitute_entities(true); //
			_paroleCaricate = 0;
			_kanjiCaricati = 0;
			_esempiCaricati = 0;
			_lezioniCaricate = 0;
			result = true;
			_parserXmlAttributeFound = parser.signal_attribute_lang ().connect (sigc::mem_fun (this, &Controller::on_signal_attribute_found) );
			_parserXmlParolaImported = parser.signal_parola_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_parola_loaded) );
			_parserXmlKanjiImported = parser.signal_kanji_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_kanji_loaded) );
			_parserXmlEsempioImported = parser.signal_esempio_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_esempio_loaded) );
			_parserXmlLezioneImported = parser.signal_lezione_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_lezione_loaded) );
			_parserXmlImportEnd = parser.signal_import_end ().connect (sigc::mem_fun (this, &Controller::on_signal_import_end) );
			parser.parse_file(filename);
#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
		}
		catch(const xmlpp::exception& ex)
		{
			std::cout << "libxml++ exception: " << ex.what() << std::endl;
			result = false;
		}
#endif //LIBXMLCPP_EXCEPTIONS_ENABLED
		_parserXmlAttributeFound.disconnect ();
		_parserXmlParolaImported.disconnect();
		_parserXmlKanjiImported.disconnect();
		_parserXmlEsempioImported.disconnect();
		_parserXmlLezioneImported.disconnect();
		_parserXmlImportEnd.disconnect ();
	}
	return result;
}

template <class ItemClass>
int Controller::
save_items_to_xml_file ( list<ItemClass> &_itemsList, ofstream *xmlstr )
{
	int ni = -1;
	if ( !*xmlstr )
		cerr << "saveItemsToXmlFile:: unable to open file!" << endl;
	else
	{
		ni++;
		class list<ItemClass>::iterator _nhit = _itemsList.begin();
		class list<ItemClass>::iterator _nhend = _itemsList.end();
		while ( _nhit != _nhend )
		{
			*xmlstr << _nhit->get_xml_string ( sys_language ).raw();
			if ( xmlstr->fail() )
			{
				cerr << "saveItemsToXmlFile:: file writing error!"<< endl;
				break;
			}
			_nhit++;
			ni++;
		}
	}
	return ni;
}

void Controller::
connect_signals ( void )
{
	// main toolbar
	_saveToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_save_action_clicked) );
	_addToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_add_action_clicked) );
	_remToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_remove_action_clicked) );
	_lectioToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_lectio_action_clicked) );
	_searchToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_search_action_clicked) );
	_testToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_test_action_clicked) );
	_infoToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_info_action_clicked) );
	_resetToolButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_reset_action_clicked) );
	_quickSearchEntry->signal_icon_press ().connect (sigc::mem_fun (this, &Controller::on_quick_search_icon_clicked) );
	_quickSearchEntry->get_buffer ()->signal_inserted_text ().connect (sigc::mem_fun (this, &Controller::on_quick_search_text_inserted) );
	_quickSearchEntry->get_buffer ()->signal_deleted_text ().connect (sigc::mem_fun (this, &Controller::on_quick_search_text_deleted) );
	// main menu
	_importMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_import_action_clicked) );
	_exportMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_export_action_clicked) );
	_saveMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_save_action_clicked) );
	_quitMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_quit_action_clicked) );
	_addMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_add_action_clicked) );
	_remMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_remove_action_clicked) );
	_lectioMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_lectio_action_clicked) );
	_resetMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_reset_action_clicked) );
	_infoMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_info_action_clicked) );
	_aboutMenuItem->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_about_action_clicked) );
	// search item win
	_srchItemPulisciButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_search_default_button_clicked) );
	_srchItemApplicaButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_search_apply_button_clicked) );
	// main win
	_mainWin->signal_focus_in_event ().connect (sigc::mem_fun (this, &Controller::on_main_win_focus_in) );
	_mainWin->signal_focus_out_event ().connect (sigc::mem_fun (this, &Controller::on_main_win_focus_out) );
	_mainNotebook->signal_switch_page ().connect (sigc::mem_fun (this, &Controller::on_main_page_switch) );
	// page parole
	_paroleDictList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_parole_tree_double_clicked) );
	_paroleDictSelection->signal_changed ().connect (sigc::mem_fun (this, &Controller::on_items_list_selection_changed) );
	// quick search parole menu
	_quickSearchParoleMenuItem1->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchParoleMenuItem1) );
	_quickSearchParoleMenuItem2->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchParoleMenuItem2) );
	_quickSearchParoleMenuItem3->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchParoleMenuItem3) );
	_quickSearchParoleMenuItem4->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchParoleMenuItem4) );
	_quickSearchParoleMenuItem5->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchParoleMenuItem5) );
	// page kanji
	_kanjiDictList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_kanji_tree_double_clicked) );
	_kanjiDictSelection->signal_changed ().connect (sigc::mem_fun (this, &Controller::on_items_list_selection_changed) );
	// quick search kanji menu
	_quickSearchKanjiMenuItem1->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem1) );
	_quickSearchKanjiMenuItem2->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem2) );
	_quickSearchKanjiMenuItem3->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem3) );
	_quickSearchKanjiMenuItem4->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem4) );
	_quickSearchKanjiMenuItem5->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem5) );
	_quickSearchKanjiMenuItem6->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem6) );
	_quickSearchKanjiMenuItem7->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchKanjiMenuItem7) );
	// page esempi
	_esempiDictList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_esempi_tree_double_clicked) );
	_esempiDictSelection->signal_changed ().connect (sigc::mem_fun (this, &Controller::on_items_list_selection_changed) );
	// quick search esempi menu
	_quickSearchEsempiMenuItem1->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchEsempiMenuItem1) );
	_quickSearchEsempiMenuItem2->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchEsempiMenuItem2) );
	_quickSearchEsempiMenuItem3->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchEsempiMenuItem3) );
	_quickSearchEsempiMenuItem4->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchEsempiMenuItem4) );
	// page lezioni
	_lezioniDictList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_lezioni_tree_double_clicked) );
	_lezioniDictSelection->signal_changed ().connect (sigc::mem_fun (this, &Controller::on_items_list_selection_changed) );
	// quick search lezioni menu
	_quickSearchLezioniMenuItem1->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchLezioniMenuItem1) );
	_quickSearchLezioniMenuItem2->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchLezioniMenuItem2) );
	_quickSearchLezioniMenuItem3->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchLezioniMenuItem3) );
	_quickSearchLezioniMenuItem4->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchLezioniMenuItem4) );
	_quickSearchLezioniMenuItem5->signal_toggled ().connect (sigc::bind<Gtk::RadioMenuItem*>(sigc::mem_fun (this, &Controller::on_quick_search_menu_toggled), _quickSearchLezioniMenuItem5) );
	// add Parola win
	_newParConfButton->signal_clicked ().connect ( sigc::mem_fun (this, &Controller::on_add_parola_confirm_button_clicked) );
	_newParAnnuButton->signal_clicked ().connect ( sigc::bind<Gtk::Window*>( sigc::mem_fun (this, &Controller::on_cancel_button_clicked), _addParWin ) );
	// add Kanji win
	_newKnjAnnullaButton->signal_clicked ().connect (sigc::bind<Gtk::Window*>( sigc::mem_fun (this, &Controller::on_cancel_button_clicked), _addKnjWin ) );
	_newKnjConfermaButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_add_kanji_confirm_button_clicked) );
	// add Esempio win
	_newExaAnnullaButton->signal_clicked ().connect (sigc::bind<Gtk::Window*>( sigc::mem_fun (this, &Controller::on_cancel_button_clicked), _addExaWin ) );
	_newExaConfermaButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_add_esempio_confirm_button_clicked) );
	// add Lezione win
	_addLezAnnullaButton->signal_clicked ().connect (sigc::bind<Gtk::Window*>( sigc::mem_fun (this, &Controller::on_cancel_button_clicked), _addLezWin ) );
	_addLezConfermaButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_add_lectio_confirm_button_clicked) );
	_addLezParList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_lectio_contenuto_tree_button_dx_clicked) );
	_addLezKnjList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_lectio_contenuto_tree_button_dx_clicked) );
	_addLezExaList->signal_button_press_event ().connect_notify (sigc::mem_fun (this, &Controller::on_lectio_contenuto_tree_button_dx_clicked) );
	_lectioItemMenuRemove->signal_activate ().connect (sigc::mem_fun (this, &Controller::on_menu_lectio_remove_item_selected) );
	// add To Lezione win
	_addToLectioCombobox->signal_changed ().connect (sigc::mem_fun (this, &Controller::on_add_to_lectio_selection_changed) );
	_addToLectioAnnullaButton->signal_clicked ().connect (sigc::bind<Gtk::Window*>( sigc::mem_fun (this, &Controller::on_cancel_button_clicked), _addToLezioneWin ) );
	_addToLectioConfermaButton->signal_clicked ().connect (sigc::mem_fun (this, &Controller::on_add_to_lectio_confirm_button_clicked) );
	// test controller
	_testCtrl->signal_items_changed ().connect (sigc::mem_fun (this, &Controller::on_signal_items_changed) );
}

void Controller::
on_cancel_button_clicked ( Gtk::Window *win )
{
	win->hide ();
}

bool Controller::
on_main_win_focus_in ( GdkEventFocus *event )
{
	if ( _startingApp == STATUS_STARTING )
	{
		Glib::Threads::Thread *loader = Glib::Threads::Thread::create (sigc::bind<Glib::ustring&>(sigc::mem_fun (this, &Controller::load_data), _dataFilename ) );
		_startingApp = STATUS_LOADING;
	}
	_mainMenuBar->set_sensitive ( true );
	_mainToolbar->set_sensitive ( true );
	switch ( _mainPage )
	{
		case 0:
			_paroleDictList->set_sensitive ( true );
			break;
		case 1:
			_kanjiDictList->set_sensitive ( true );
			break;
		case 3:
			_esempiDictList->set_sensitive ( true );
			break;
		case 4:
			_lezioniDictList->set_sensitive ( true );
			break;
	}
	return false;
}

bool Controller::
on_main_win_focus_out ( GdkEventFocus *event )
{
	_mainMenuBar->set_sensitive ( false );
	_mainToolbar->set_sensitive ( false );
	switch ( _mainPage )
	{
		case 0:
			_paroleDictList->set_sensitive ( false );
			break;
		case 1:
			_kanjiDictList->set_sensitive ( false );
			break;
		case 3:
			_esempiDictList->set_sensitive ( false );
			break;
		case 4:
			_lezioniDictList->set_sensitive ( false );
			break;
	}
	return false;
}

void Controller::
on_main_page_switch ( Gtk::Widget *page, guint page_num )
{
	_mainPage = page_num;
	on_items_list_selection_changed ();
	switch ( _mainPage )
	{
		case 0:
			// search win
			_srchItemWin->set_title ( Glib::ustring ( "Cerca parole" ) );
			_srchItemFrame1->set_visible ( true );
			_srchItemLabel1->set_text ( "tipo" );
			_srchItemListStore1->clear ();
			load_pop_up_button ( _popUpParTipoStrings->begin(), _popUpParTipoStrings->end(), _srchItemListStore1 );
			_srchItemComboBox1->set_active ( 0 );
			_srchItemListStore3->clear ();
			load_pop_up_button ( _popUpCampoStrings->begin(), _popUpCampoStrings->end() - 16, _srchItemListStore3 );
			_srchItemComboBox3->set_active ( 0 );
			// info win
			_infoItemWin->set_title ( Glib::ustring ( "Informazioni sulla Parola" ) );
			_infoItemProLabel1->set_text ( Glib::ustring ( "言葉" ) );
			_infoItemProLabel2->set_text ( Glib::ustring ( "読み方" ) );
			_infoItemProLabel3->set_text ( Glib::ustring ( "Traduzione" ) );
			_infoItemProLabel4->set_text ( Glib::ustring ( "Tipo" ) );
			_infoItemProLabel5->set_text ( Glib::ustring ( "Contesto" ) );
			_infoItemProLabel2->set_visible ( true );
			_infoItemProValLabel2->set_visible ( true );
			_infoItemProLabel3->set_visible ( true );
			_infoItemProValLabel3->set_visible ( true );
			_infoItemProLabel4->set_visible ( true );
			_infoItemProValLabel4->set_visible ( true );
			_infoItemProLabel5->set_visible ( true );
			_infoItemProValLabel5->set_visible ( true );
			_infoItemProLabel6->set_visible ( false );
			_infoItemProValLabel6->set_visible ( false );
			_infoItemProLabel7->set_visible ( false );
			_infoItemProValLabel7->set_visible ( false );
			_infoItemProLabel8->set_visible ( false );
			_infoItemProValLabel8->set_visible ( false );
			_infoItemStatsBox->set_visible ( true );
			_infoItemVal1Label2->set_text ( Glib::ustring ( "Sintassi" ) );
			_infoItemDate1Label2->set_text ( Glib::ustring ( "Sintassi" ) );
			_infoItemVal1Label3->set_visible ( true );
			_infoItemVal2Label3->set_visible ( true );
			_infoItemDate1Label3->set_visible ( true );
			_infoItemDate2Label3->set_visible ( true );
			_infoItemVal1Label4->set_visible ( true );
			_infoItemVal2Label4->set_visible ( true );
			_infoItemDate1Label4->set_visible ( true );
			_infoItemDate2Label4->set_visible ( true );
			_infoItemTabLabel1->set_text ( Glib::ustring ( "漢字" ) );
			_infoItemList1->set_model ( _infoItemKanjiListStore );
			_infoItemList1Col1->set_title ( Glib::ustring ( "漢字" ) );
			_infoItemList1Col2->set_title ( Glib::ustring ( "Tratti" ) );
			_infoItemList1Col3->set_title ( Glib::ustring ( "Radicale" ) );
			_infoItemTabLabel2->set_text ( Glib::ustring ( "Esempi" ) );
			_infoItemList2->set_model (_infoItemEsempiListStore);
			_infoItemList2Col1->set_title ( Glib::ustring ( "Frase" ) );
			_infoItemList2Col2->set_visible ( false );
			_infoItemList2Col3->set_visible ( false );
			break;
		case 1:
			// search win
			_srchItemWin->set_title ( Glib::ustring ( "Cerca kanji" ) );
			_srchItemFrame1->set_visible ( true );
			_srchItemLabel1->set_text ( "tratti" );
			_srchItemListStore1->clear ();
			load_pop_up_button ( _popUpTrattiStrings->begin(), _popUpTrattiStrings->end(), _srchItemListStore1 );
			_srchItemComboBox1->set_active ( 0 );
			_srchItemListStore3->clear ();
			load_pop_up_button ( _popUpCampoStrings->begin() + 5, _popUpCampoStrings->end() - 9, _srchItemListStore3 );
			_srchItemComboBox3->set_active ( 0 );
			// info win
			_infoItemWin->set_title ( Glib::ustring ( "Informazioni sul Kanji" ) );
			_infoItemProLabel1->set_text ( Glib::ustring ( "漢字" ) );
			_infoItemProLabel2->set_text ( Glib::ustring ( "Tratti" ) );
			_infoItemProLabel3->set_text ( Glib::ustring ( "Radicale" ) );
			_infoItemProLabel4->set_text ( Glib::ustring ( "Tratti radicale" ) );
			_infoItemProLabel5->set_text ( Glib::ustring ( "訓読み" ) );
			_infoItemProLabel6->set_text ( Glib::ustring ( "音読み" ) );
			_infoItemProLabel7->set_text ( Glib::ustring ( "Significato" ) );
			_infoItemProLabel8->set_text ( Glib::ustring ( "Contesto" ) );
			_infoItemProLabel2->set_visible ( true );
			_infoItemProValLabel2->set_visible ( true );
			_infoItemProLabel3->set_visible ( true );
			_infoItemProValLabel3->set_visible ( true );
			_infoItemProLabel4->set_visible ( true );
			_infoItemProValLabel4->set_visible ( true );
			_infoItemProLabel5->set_visible ( true );
			_infoItemProValLabel5->set_visible ( true );
			_infoItemProLabel6->set_visible ( true );
			_infoItemProValLabel6->set_visible ( true );
			_infoItemProLabel7->set_visible ( true );
			_infoItemProValLabel7->set_visible ( true );
			_infoItemProLabel8->set_visible ( true );
			_infoItemProValLabel8->set_visible ( true );
			_infoItemStatsBox->set_visible ( true );
			_infoItemVal1Label2->set_text ( Glib::ustring ( "Letture" ) );
			_infoItemDate1Label2->set_text ( Glib::ustring ( "Letture" ) );
			_infoItemVal1Label3->set_visible ( false );
			_infoItemVal2Label3->set_visible ( false );
			_infoItemDate1Label3->set_visible ( false );
			_infoItemDate2Label3->set_visible ( false );
			_infoItemVal1Label4->set_visible ( false );
			_infoItemVal2Label4->set_visible ( false );
			_infoItemDate1Label4->set_visible ( false );
			_infoItemDate2Label4->set_visible ( false );
			_infoItemTabLabel1->set_text ( Glib::ustring ( "Parole" ) );
			_infoItemList1->set_model ( _infoItemParoleListStore );
			_infoItemList1Col1->set_title ( Glib::ustring ( "Parola" ) );
			_infoItemList1Col2->set_title ( Glib::ustring ( "言葉" ) );
			_infoItemList1Col3->set_title ( Glib::ustring ( "読み方" ) );
			_infoItemTabLabel2->set_text ( Glib::ustring ( "Esempi" ) );
			_infoItemList2->set_model (_infoItemEsempiListStore);
			_infoItemList2Col1->set_title ( Glib::ustring ( "Frase" ) );
			_infoItemList2Col2->set_visible ( false );
			_infoItemList2Col3->set_visible ( false );
			break;
		case 3:
			// search win
			_srchItemWin->set_title ( Glib::ustring ( "Cerca esempi" ) );
			_srchItemFrame1->set_visible ( false );
			_srchItemListStore3->clear ();
			load_pop_up_button ( _popUpCampoStrings->begin() + 12, _popUpCampoStrings->end() - 5, _srchItemListStore3 );
			_srchItemComboBox3->set_active ( 0 );
			// info win
			_infoItemWin->set_title ( Glib::ustring ( "Informazioni sull'Esempio" ) );
			_infoItemProLabel1->set_text ( Glib::ustring ( "Frase" ) );
			_infoItemProLabel2->set_text ( Glib::ustring ( "Traduzione" ) );
			_infoItemProLabel3->set_text ( Glib::ustring ( "Contesto" ) );
			_infoItemProLabel2->set_visible ( true );
			_infoItemProValLabel2->set_visible ( true );
			_infoItemProLabel3->set_visible ( true );
			_infoItemProValLabel3->set_visible ( true );
			_infoItemProLabel4->set_visible ( false );
			_infoItemProValLabel4->set_visible ( false );
			_infoItemProLabel5->set_visible ( false );
			_infoItemProValLabel5->set_visible ( false );
			_infoItemProLabel6->set_visible ( false );
			_infoItemProValLabel6->set_visible ( false );
			_infoItemProLabel7->set_visible ( false );
			_infoItemProValLabel7->set_visible ( false );
			_infoItemProLabel8->set_visible ( false );
			_infoItemProValLabel8->set_visible ( false );
			_infoItemStatsBox->set_visible ( false );
			_infoItemTabLabel1->set_text ( Glib::ustring ( "Parole" ) );
			_infoItemList1->set_model ( _infoItemParoleListStore );
			_infoItemList1Col1->set_title ( Glib::ustring ( "Parola" ) );
			_infoItemList1Col2->set_title ( Glib::ustring ( "言葉" ) );
			_infoItemList1Col3->set_title ( Glib::ustring ( "読み方" ) );
			_infoItemTabLabel2->set_text ( Glib::ustring ( "漢字" ) );
			_infoItemList2->set_model ( _infoItemKanjiListStore );
			_infoItemList2Col1->set_title ( Glib::ustring ( "漢字" ) );
			_infoItemList2Col2->set_title ( Glib::ustring ( "Tratti" ) );
			_infoItemList2Col3->set_title ( Glib::ustring ( "Radicale" ) );
			_infoItemList2Col2->set_visible ( true );
			_infoItemList2Col3->set_visible ( true );
			break;
		case 4:
			// search win
			_srchItemWin->set_title ( Glib::ustring ( "Cerca lezioni" ) );
			_srchItemFrame1->set_visible ( false );
			_srchItemListStore3->clear ();
			load_pop_up_button ( _popUpCampoStrings->begin() + 16, _popUpCampoStrings->end(), _srchItemListStore3 );
			_srchItemComboBox3->set_active ( 0 );
			// info win
			_infoItemWin->set_title ( Glib::ustring ( "Informazioni sulla Lezione" ) );
			_infoItemProLabel1->set_text ( Glib::ustring ( "Nome" ) );
			_infoItemProLabel2->set_visible ( false );
			_infoItemProValLabel2->set_visible ( false );
			_infoItemProLabel3->set_visible ( false );
			_infoItemProValLabel3->set_visible ( false );
			_infoItemProLabel4->set_visible ( false );
			_infoItemProValLabel4->set_visible ( false );
			_infoItemProLabel5->set_visible ( false );
			_infoItemProValLabel5->set_visible ( false );
			_infoItemProLabel6->set_visible ( false );
			_infoItemProValLabel6->set_visible ( false );
			_infoItemProLabel7->set_visible ( false );
			_infoItemProValLabel7->set_visible ( false );
			_infoItemProLabel8->set_visible ( false );
			_infoItemProValLabel8->set_visible ( false );
			_infoItemStatsBox->set_visible ( false );
			_infoItemTabLabel1->set_text ( Glib::ustring ( "Parole" ) );
			_infoItemList1->set_model ( _infoItemParoleListStore );
			_infoItemList1Col1->set_title ( Glib::ustring ( "Parola" ) );
			_infoItemList1Col2->set_title ( Glib::ustring ( "言葉" ) );
			_infoItemList1Col3->set_title ( Glib::ustring ( "読み方" ) );
			_infoItemTabLabel2->set_text ( Glib::ustring ( "漢字" ) );
			_infoItemList2->set_model ( _infoItemKanjiListStore );
			_infoItemList2Col1->set_title ( Glib::ustring ( "漢字" ) );
			_infoItemList2Col2->set_title ( Glib::ustring ( "Tratti" ) );
			_infoItemList2Col3->set_title ( Glib::ustring ( "Radicale" ) );
			_infoItemList2Col2->set_visible ( true );
			_infoItemList2Col3->set_visible ( true );
			break;
	}
}

void Controller::
on_items_list_selection_changed ( void )
{
	Glib::ustring _messaggio;
	int _nr = 0;
	switch ( _mainPage )
	{
		case 0:
			_nr = _paroleDictSelection->count_selected_rows ();
			if ( _nr == 0 )
				_messaggio.append ( Glib::ustring::compose( "Nessuna parola selezionata di %1.", Glib::ustring::format( _parole->size() ) ) );
			if ( _nr == 1 )
				_messaggio.append ( Glib::ustring::compose( "Una parola selezionata di %1.", Glib::ustring::format( _parole->size() ) ) );
			if ( _nr > 1 )
				_messaggio.append ( Glib::ustring::compose( "%1 parole selezionate di %2.", Glib::ustring::format( _nr ), Glib::ustring::format( _parole->size() ) ) );
			break;
		case 1:
			_nr = _kanjiDictSelection->count_selected_rows ();
			if ( _nr == 0 )
				_messaggio.append ( Glib::ustring::compose( "Nessun kanji selezionato di %1.", Glib::ustring::format( _kanji->size() ) ) );
			if ( _nr == 1 )
				_messaggio.append ( Glib::ustring::compose( "Un kanji selezionato di %1.", Glib::ustring::format( _kanji->size() ) ) );
			if ( _nr > 1 )
				_messaggio.append ( Glib::ustring::compose( "%1 kanji selezionati di %2.", Glib::ustring::format( _nr ), Glib::ustring::format( _kanji->size() ) ) );
			break;
		case 2:
			_messaggio.append ( "Forme non ancora implementate." );
			break;
		case 3:
			_nr = _esempiDictSelection->count_selected_rows ();
			if ( _nr == 0 )
				_messaggio.append ( Glib::ustring::compose( "Nessun esempio selezionato di %1.", Glib::ustring::format( _esempi->size() ) ) );
			if ( _nr == 1 )
				_messaggio.append ( Glib::ustring::compose( "Un esempio selezionato di %1.", Glib::ustring::format( _esempi->size() ) ) );
			if ( _nr > 1 )
				_messaggio.append ( Glib::ustring::compose( "%1 esempi selezionati di %2.", Glib::ustring::format( _nr ), Glib::ustring::format( _esempi->size() ) ) );
			break;
		case 4:
			_nr = _lezioniDictSelection->count_selected_rows ();
			if ( _nr == 0 )
				_messaggio.append ( Glib::ustring::compose( "Nessuna lezione selezionata di %1.", Glib::ustring::format( _lezioni->size() ) ) );
			if ( _nr > 0 )
				_messaggio.append ( Glib::ustring::compose( "Una lezione selezionata di %1.", Glib::ustring::format( _lezioni->size() ) ) );
			break;
	}
	_mainStatus->pop ( _stsItemSelId );
	_mainStatus->push ( _messaggio, _stsItemSelId );
	if ( _nr > 0 )
	{
		if ( !_remToolButton->get_sensitive () )
		{
			_remToolButton->set_sensitive ( true );
			_remMenuItem->set_sensitive ( true );
		}
		if ( !_infoToolButton->get_sensitive () )
		{
			_infoToolButton->set_sensitive ( true );
			_infoMenuItem->set_sensitive ( true );
		}
		if ( _mainPage < 4 )
		{
			if ( !_lectioToolButton->get_sensitive () )
			{
				_lectioToolButton->set_sensitive ( true );
				_lectioMenuItem->set_sensitive ( true );
			}
		}
		else
		{
			if ( _lectioToolButton->get_sensitive () )
			{
				_lectioToolButton->set_sensitive ( false );
				_lectioMenuItem->set_sensitive ( false );
			}
		}
		if ( _mainPage < 3 )
		{
			if ( !_resetToolButton->get_sensitive () )
			{
				_resetToolButton->set_sensitive ( true );
				_resetMenuItem->set_sensitive ( true );
			}
		}
		else
		{
			if ( _resetToolButton->get_sensitive () )
			{
				_resetToolButton->set_sensitive ( false );
				_resetMenuItem->set_sensitive ( false );
			}
		}
		if ( !_exportMenuItem->get_sensitive () )
		{
			//_exportToolButton->set_sensitive ( true );
			_exportMenuItem->set_sensitive ( true );
		}
	}
	else
	{
		if ( _remToolButton->get_sensitive () )
		{
			_remToolButton->set_sensitive ( false );
			_remMenuItem->set_sensitive ( false );
		}
		if ( _infoToolButton->get_sensitive () )
		{
			_infoToolButton->set_sensitive ( false );
			_infoMenuItem->set_sensitive ( false );
		}
		if ( _lectioToolButton->get_sensitive () )
		{
			_lectioToolButton->set_sensitive ( false  );
			_lectioMenuItem->set_sensitive ( false );
		}
		if ( _resetToolButton->get_sensitive () )
		{
			_resetToolButton->set_sensitive ( false );
			_resetMenuItem->set_sensitive ( false );
		}
		if ( _exportMenuItem->get_sensitive () )
		{
			//_exportToolButton->set_sensitive ( false );
			_exportMenuItem->set_sensitive ( false );
		}
	}
}

void Controller::
get_tree_row_ref ( const vector<Gtk::TreePath> &_sel, Glib::RefPtr<Gtk::TreeModel> _listModel, vector<Gtk::TreeRowReference> &_selRef )
{
	vector<Gtk::TreePath>::const_iterator _iter = _sel.begin();
	vector<Gtk::TreePath>::const_iterator _end = _sel.end();
	while ( _iter != _end )
	{
		Gtk::TreeRowReference _ref = Gtk::TreeRowReference ( _listModel, *_iter );
		_selRef.push_back ( _ref );
		_iter++;
	}
}

void Controller::
load_pop_up_button ( vector<Glib::ustring>::iterator _start, vector<Glib::ustring>::iterator _end, Glib::RefPtr<Gtk::ListStore> _popUpList )
{
	while ( _start != _end )
	{
		Gtk::TreeModel::iterator iter = _popUpList->append();
		Gtk::TreeModel::Row row = *iter;
		row[_buttonPopUpColumn->columnCell] = *_start;
		_start++;
	}
}

void Controller::
on_import_action_clicked ( void )
{
	sigc::connection _parserXmlParolaImported;
	sigc::connection _parserXmlKanjiImported;
	sigc::connection _parserXmlEsempioImported;
	sigc::connection _parserXmlLezioneImported;
	sigc::connection _parserXmlImportEnd;
	Glib::ustring filename;
	Glib::RefPtr<Gtk::FileFilter> xml_filter = Gtk::FileFilter::create();
	xml_filter->set_name ( "XML" );
	xml_filter->add_mime_type( "text/xml" );
	Gtk::FileChooserDialog fco( *_mainWin, Glib::ustring ( "Importa elementi in formato XML" ), Gtk::FILE_CHOOSER_ACTION_OPEN );
	fco.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
	fco.add_button (Glib::ustring ( "Importa" ), Gtk::RESPONSE_OK);
	fco.add_filter ( xml_filter );
	int result = fco.run();
	switch ( result )
	{
		case Gtk::RESPONSE_OK:
			filename = fco.get_filename();
			break;
		case Gtk::RESPONSE_CANCEL:
			filename = Glib::ustring ( "" );
			break;
	}
	if ( filename != Glib::ustring ( "" ) )
	{
		// Parse the entire document in one go:
#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
		try
		{
#endif //LIBXMLCPP_EXCEPTIONS_ENABLED 
			ParserXML parser;
			parser.set_substitute_entities(true); //
			_paroleCaricate = 0;
			_kanjiCaricati = 0;
			_esempiCaricati = 0;
			_lezioniCaricate = 0;
			_parserXmlParolaImported = parser.signal_parola_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_parola_loaded) );
			_parserXmlKanjiImported = parser.signal_kanji_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_kanji_loaded) );
			_parserXmlEsempioImported = parser.signal_esempio_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_esempio_loaded) );
			_parserXmlLezioneImported = parser.signal_lezione_imported ().connect (sigc::mem_fun (this, &Controller::on_signal_lezione_loaded) );
			_parserXmlImportEnd = parser.signal_import_end ().connect (sigc::mem_fun (this, &Controller::on_signal_import_end) );
			parser.parse_file(filename);
#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
		}
		catch(const xmlpp::exception& ex)
		{
			std::cout << "libxml++ exception: " << ex.what() << std::endl;
		}
#endif //LIBXMLCPP_EXCEPTIONS_ENABLED
		_parserXmlParolaImported.disconnect();
		_parserXmlKanjiImported.disconnect();
		_parserXmlEsempioImported.disconnect();
		_parserXmlLezioneImported.disconnect();
		_parserXmlImportEnd.disconnect ();
	}
	if ( _shouldSave )
	{
		_saveToolButton->set_sensitive ( true );
		_saveMenuItem->set_sensitive ( true );
	}
}

void Controller::
on_export_action_clicked ( void )
{
	Glib::ustring filename, suffix, xmls;
	vector<Gtk::TreePath> _selected;
	Glib::RefPtr<Gtk::FileFilter> xml_filter = Gtk::FileFilter::create();
	xml_filter->set_name ( "XML" );
	xml_filter->add_mime_type( "text/xml" );
	Gtk::FileChooserDialog fco( *_mainWin, Glib::ustring ( "Esporta elementi in formato XML" ), Gtk::FILE_CHOOSER_ACTION_SAVE );
	fco.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
	fco.add_button (Glib::ustring ( "Esporta" ), Gtk::RESPONSE_OK);
	fco.set_create_folders ( true );
	fco.add_filter ( xml_filter );
	int result = fco.run();
	switch ( result )
	{
		case Gtk::RESPONSE_OK:
			filename = fco.get_filename();
			suffix = filename.size() > 4 ? filename.substr( filename.size() - 4, 4 ).lowercase () : filename;
			xmls = Glib::ustring ( ".xml" );
			if ( suffix != xmls )
				filename += xmls;
			break;
		case Gtk::RESPONSE_CANCEL:
			filename = Glib::ustring ( "" );
			break;
	}
	if ( filename != Glib::ustring ( "" ) )
	{
		bool nullaOsta = true;
		Glib::RefPtr<Gio::File> expFile = Gio::File::create_for_path ( filename );
		if ( expFile->query_exists () )
		{
			Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "Il file selezionato esiste già, vuoi sovrascriverlo?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
			int res_id = _alertDialog->run();
			delete _alertDialog;
			if ( res_id == Gtk::RESPONSE_NO )
				nullaOsta = false;
		}
		if ( nullaOsta )
		{
			ofstream outfile ( filename.c_str(), ios_base::out );
			if ( !outfile )
				cerr << "exportToXML:: unable to open file \"" << filename << "\"" << endl;
			else
			{
				outfile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
				outfile << "<nihongo>\n";
				switch ( _mainPage )
				{
					case 0:
						_selected = _paroleDictSelection->get_selected_rows ();
						export_parole_to_xml ( &outfile, _selected );
						break;
					case 1:
						_selected = _kanjiDictSelection->get_selected_rows ();
						export_kanji_to_xml ( &outfile, _selected );
						break;
					case 2:
						cerr << "export forma" << endl;
						break;
					case 3:
						_selected = _esempiDictSelection->get_selected_rows ();
						export_esempi_to_xml ( &outfile, _selected );
						break;
					case 4:
						_selected = _lezioniDictSelection->get_selected_rows ();
						export_lezioni_to_xml ( &outfile, _selected );
						break;
				}
				outfile << "</nihongo>";
				if ( outfile.fail() )
					cerr << "exportToXML:: file writing error! \"" << filename << "\"" << endl;
				outfile.close();
			}
		}
	}
}

void Controller::
on_save_action_clicked ( void )
{
	if ( save_data( _dataFilename ) )
	{
		_saveToolButton->set_sensitive ( false );
		_saveMenuItem->set_sensitive ( false );
	}
}

void Controller::
on_add_action_clicked ( void )
{
	switch ( _mainPage )
	{
		case 0: // page parole
			_paroleDictSelection->unselect_all ();
			_newKotoba->set_text ( "" );
			_newYomikata->set_text ( "" );
			_newParTraduzione->set_text ( "" );
			_newTipoCombobox->set_active ( 0 );
			_newParContesto->set_text ( "" );
			_newKotoba->set_sensitive ( true );
			_newYomikata->set_sensitive ( true );
			_newParTraduzione->set_sensitive ( true );
			_addParWin->present ();
			break;
		case 1:	// page kanji
			_kanjiDictSelection->unselect_all ();
			_newKanji->set_text ( "" );
			_newRadicale->set_text ( "" );
			_newTratti->set_text ( "" );
			_newTrattiRadicale->set_text ( "" );
			_newKunyomi->set_text ( "" );
			_newOnyomi->set_text ( "" );
			_newSignificato->set_text ( "" );
			_newKnjContesto->set_text ( "" );
			_newKanji->set_sensitive ( true );
			_newTratti->set_sensitive ( true );
			_newKunyomi->set_sensitive ( true );
			_newOnyomi->set_sensitive ( true );
			_newSignificato->set_sensitive ( true );
			_addKnjWin->present ();
			break;
		case 2:
			cerr << "add forma" << endl;
			break;
		case 3: // page esempi
			_esempiDictSelection->unselect_all ();
			_newFrase->set_text ( "" );
			_newExaTraduzione->set_text ( "" );
			_newExaContesto->set_text ( "" );
			_newFrase->set_sensitive ( true );
			_newExaTraduzione->set_sensitive ( true );
			_addExaWin->present ();
			break;
		case 4: // page lezioni
			_lezioniDictSelection->unselect_all ();
			_addLezEntry->set_text ( "" );
			_addLezParListStore->clear();
			_addLezWin->present ();
			break;
	}
}

void Controller::
on_remove_action_clicked ( void )
{
	Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "Vuoi eliminare definitivamente gli elementi selezionati?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
	int res_id = _alertDialog->run();
	delete _alertDialog;
	if ( res_id == Gtk::RESPONSE_YES )
	{
		vector<Gtk::TreePath> _selected;
		switch ( _mainPage )
		{
			case 0:
				_selected = _paroleDictSelection->get_selected_rows ();
				parole_tree_remove_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
			case 1:
				_selected = _kanjiDictSelection->get_selected_rows ();
				kanji_tree_remove_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
			case 2:
				cerr << "remove forma" << endl;
				break;
			case 3:
				_selected = _esempiDictSelection->get_selected_rows ();
				esempi_tree_remove_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
			case 4:
				_selected = _lezioniDictSelection->get_selected_rows ();
				lezioni_tree_remove_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
		}
		_shouldSave = true;
	}
}

void Controller::
on_lectio_action_clicked ( void )
{
	_addToLezioneWin->present();
}

void Controller::
on_search_action_clicked ( void )
{
	if ( _mainPage != 2 )
		_srchItemWin->present ();
}

void Controller::
on_test_action_clicked ( void )
{
	_testCtrl->init_window ();
	_testCtrl->present_window ();
}

void Controller::
on_info_action_clicked ( void )
{
	vector<Gtk::TreePath> _selected;
	int nrSel = 0;
	Glib::RefPtr<Gtk::TreeModel> _listModel;
	vector<Gtk::TreePath>::const_iterator _iter;
	Gtk::TreeModel::iterator _iterView;
	Gtk::TreeModel::Row _row;
	switch ( _mainPage )
	{
		case 0:
			_selected = _paroleDictSelection->get_selected_rows ();
			nrSel = _paroleDictSelection->count_selected_rows ();
			_listModel = _paroleDictList->get_model ();
			break;
		case 1:
			_selected = _kanjiDictSelection->get_selected_rows ();
			nrSel = _kanjiDictSelection->count_selected_rows ();
			_listModel = _kanjiDictList->get_model ();
			break;
		case 3:
			_selected = _esempiDictSelection->get_selected_rows ();
			nrSel = _esempiDictSelection->count_selected_rows ();
			_listModel = _esempiDictList->get_model ();
			break;
		case 4:
			_selected = _lezioniDictSelection->get_selected_rows ();
			nrSel = _lezioniDictSelection->count_selected_rows ();
			_listModel = _lezioniDictList->get_model ();
			break;
		default:
			cerr << "info on selected items" << endl;
			break;
	}
	if ( nrSel > 0 )
	{
		Voce *vox = 0;
		_iter = _selected.begin ();
		_iterView = _listModel->get_iter ( *_iter );
		_row = *_iterView;
		switch ( _mainPage )
		{
			case 0:
				vox = populate_parola_info ( _row );
				break;
			case 1:
				vox = populate_kanji_info ( _row );
				break;
			case 3:
				populate_esempio_info ( _row );
				break;
			case 4:
				populate_lezione_info ( _row );
				break;
			default:
				cerr << "c'è stato un errore?" << endl;
				break;
		}
		populate_item_stats ( vox );
		_infoItemWin->present ();
	}
}

void Controller::
on_reset_action_clicked ( void )
{
	Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "Vuoi azzerare definitivamente le statistiche degli elementi selezionati?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
	int res_id = _alertDialog->run();
	delete _alertDialog;
	if ( res_id == Gtk::RESPONSE_YES )
	{
		vector<Gtk::TreePath> _selected;
		switch ( _mainPage )
		{
			case 0:
				_selected = _paroleDictSelection->get_selected_rows ();
				parole_tree_reset_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
			case 1:
				_selected = _kanjiDictSelection->get_selected_rows ();
				kanji_tree_reset_selected_rows ( _selected );
				_saveToolButton->set_sensitive ( true );
				_saveMenuItem->set_sensitive ( true );
				break;
			case 2:
				cerr << "reset forma" << endl;
				break;
		}
		_shouldSave = true;
	}
}

void Controller::
on_quit_action_clicked ( void )
{
	_thisApp->quit ();
}

void Controller::
on_about_action_clicked ( void )
{
	Gtk::AboutDialog *_about;
	Glib::RefPtr<Gdk::Pixbuf> _logo = _mainWin->get_icon ();
	_about = new Gtk::AboutDialog ();
	_about->set_program_name ( Glib::ustring ( "Nihongo" ) );
	_about->set_version ( Glib::ustring ( "0.3.2 (100a)" ) );
	_about->set_copyright ( Glib::ustring ( "Copyright (C) Massimiliano Maniscalco 2011 - 2012" ) );
	_about->set_license ( Glib::ustring ( "Nihongo is free software: you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nNihongo is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\nSee the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program.  If not, see <http://www.gnu.org/licenses/>." ) );
	_about->set_logo ( _logo );
	_about->signal_response ().connect (sigc::bind<Gtk::AboutDialog*>( sigc::mem_fun (this, &Controller::on_about_response), _about ) );
	_about->run ();
}

void Controller::
on_about_response ( int response_id, Gtk::AboutDialog *_about )
{
	_about->hide ();
	delete _about;
}

void Controller::
on_quick_search_icon_clicked ( Gtk::EntryIconPosition icon_position, const GdkEventButton* event)
{
	switch ( _mainPage )
	{
		case 0:
			_quickSearchParoleMenu->popup ( 0, gtk_get_current_event_time () );
			break;
		case 1:
			_quickSearchKanjiMenu->popup ( 0, gtk_get_current_event_time () );
			break;
		case 2:
			cerr << "quick search menu for forme not yet implemented" << endl;
			break;
		case 3:
			_quickSearchEsempiMenu->popup ( 0, gtk_get_current_event_time () );
			break;
		case 4:
			_quickSearchLezioniMenu->popup ( 0, gtk_get_current_event_time () );
			break;
	}
}

void Controller::
on_quick_search_text_inserted ( guint position, const gchar* chars, guint n_chars )
{
	switch ( _mainPage )
	{
		case 0:
			load_parole_in_tree_view ( true );
			break;
		case 1:
			load_kanji_in_tree_view ( true );
			break;
		case 2:
			cerr << "forma not yet implemented" << endl;
			break;
		case 3:
			load_esempi_in_tree_view ( true );
			break;
		case 4:
			load_lezioni_in_tree_view ( true );
			break;
	}
}

void Controller::
on_quick_search_text_deleted ( guint position, guint n_chars )
{
	switch ( _mainPage )
	{
		case 0:
			load_parole_in_tree_view ( true );
			break;
		case 1:
			load_kanji_in_tree_view ( true );
			break;
		case 2:
			cerr << "forma not yet implemented" << endl;
			break;
		case 3:
			load_esempi_in_tree_view ( true );
			break;
		case 4:
			load_lezioni_in_tree_view ( true );
			break;
	}
}

void Controller::
on_quick_search_menu_toggled ( Gtk::RadioMenuItem *sender )
{
	if ( sender->get_active () )
	{
		switch ( _mainPage )
		{
			case 0:
				load_parole_in_tree_view ( true );
				break;
			case 1:
				load_kanji_in_tree_view ( true );
				break;
			case 2:
				cerr << "forma not yet implemented" << endl;
				break;
			case 3:
				load_esempi_in_tree_view ( true );
				break;
			case 4:
				load_lezioni_in_tree_view ( true );
				break;
		}
	}
}

void Controller::
on_search_default_button_clicked ( void )
{
	_srchItemComboBox1->set_active ( 0 );
	_srchItemEntry2->set_text ( "" );
	_srchItemComboBox3->set_active ( 0 );
}

void Controller::
on_search_apply_button_clicked ( void )
{
	unsigned char _comboboxIndex1 = _srchItemComboBox1->get_active_row_number ();
	Glib::ustring _entryString = _srchItemEntry2->get_text ();
	unsigned char _comboboxIndex3 = _srchItemComboBox3->get_active_row_number ();
	switch ( _mainPage )
	{
		case 0:
			load_parole_in_tree_view ( true );
			break;
		case 1:
			load_kanji_in_tree_view ( true );
			break;
		case 3:
			load_esempi_in_tree_view ( true );
			break;
		case 4:
			load_lezioni_in_tree_view ( true );
			break;
	}
	_srchItemWin->hide ();
}

void Controller::
populate_item_stats ( const Voce *vox )
{
	if ( vox )
	{
		time_t rawTime = vox->get_data_esame ( 0 );
		if ( rawTime > 0)
			_infoItemDate2Label1->set_text ( vox->get_string_data_esame ( 0 ) );
		else
			_infoItemDate2Label1->set_text ( "mai eseguito" );
		rawTime = vox->get_data_esame ( 1 );
		if ( rawTime > 0)
			_infoItemDate2Label2->set_text ( vox->get_string_data_esame ( 1 ) );
		else
			_infoItemDate2Label2->set_text ( "mai eseguito" );			
		rawTime = vox->get_data_esame ( 2 );
		if ( rawTime > 0)
			_infoItemDate2Label3->set_text ( vox->get_string_data_esame ( 2 ) );
		else
			_infoItemDate2Label3->set_text ( "mai eseguito" );
		rawTime = vox->get_data_esame ( 3 );
		if ( rawTime > 0)
			_infoItemDate2Label4->set_text ( vox->get_string_data_esame ( 3 ) );
		else
			_infoItemDate2Label4->set_text ( "mai eseguito" );
		_infoItemVal2Label1->set_text ( Glib::ustring::format ( static_cast<int>( vox->get_valutazione ( 0 ) ) ) );
		_infoItemVal2Label2->set_text ( Glib::ustring::format ( static_cast<int>( vox->get_valutazione ( 1 ) ) ) );
		_infoItemVal2Label3->set_text ( Glib::ustring::format ( static_cast<int>( vox->get_valutazione ( 2 ) ) ) );
		_infoItemVal2Label4->set_text ( Glib::ustring::format ( static_cast<int>( vox->get_valutazione ( 3 ) ) ) );
		_infoItemTotLabel->set_text ( Glib::ustring::format ( vox->get_test_svolti () ) );
	}
}

void Controller::
load_parole_in_tree_view ( bool filtro )
{
	unsigned char filtroTipo = filtro ? _srchItemComboBox1->get_active_row_number () : 0;
	Glib::ustring filtroString = filtro ? _srchItemEntry2->get_text () : Glib::ustring ( "" );
	bool filtroStringValido = ( filtroString != Glib::ustring ( "" ) );
	unsigned char filtroCampo = filtro ? _srchItemComboBox3->get_active_row_number () : 0;
	Glib::ustring quickString = filtro ? _quickSearchEntry->get_text () : Glib::ustring ( "" );
	bool quickStringValido = ( quickString != Glib::ustring ( "" ) );
	unsigned char quickSearchCampo = 0;
	if ( quickStringValido )
	{
		if ( _quickSearchParoleMenuItem2->get_active () )
			quickSearchCampo = 1;
		if ( _quickSearchParoleMenuItem3->get_active () )
			quickSearchCampo = 2;
		if ( _quickSearchParoleMenuItem4->get_active () )
			quickSearchCampo = 3;
		if ( _quickSearchParoleMenuItem5->get_active () )
			quickSearchCampo = 4;
	}
	_paroleListStore->clear();
	list<Parola>::iterator iter = _parole->begin();
	list<Parola>::iterator iterEnd = _parole->end();
	while (iter != iterEnd)
	{
		bool _match = true;
		if ( filtroTipo > 0 && iter->get_tipo() != filtroTipo )
			_match = false;
		if ( _match )
		{
			if ( filtroStringValido )
			{
				switch ( filtroCampo )
				{
					case 0:
						if ( iter->get_gaikokugo().find( filtroString ) == Glib::ustring::npos && iter->get_kotoba().find( filtroString ) == Glib::ustring::npos && iter->get_yomikata().find( filtroString ) == Glib::ustring::npos && iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 1:
						if ( iter->get_gaikokugo().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 2:
						if ( iter->get_kotoba().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 3:
						if ( iter->get_yomikata().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 4:
						if ( iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
				}
			}
			if ( _match )
			{
				if ( quickStringValido )
				{
					switch ( quickSearchCampo )
					{
						case 0:
							if ( iter->get_gaikokugo().find( quickString ) == Glib::ustring::npos && iter->get_kotoba().find( quickString ) == Glib::ustring::npos && iter->get_yomikata().find( quickString ) == Glib::ustring::npos && iter->get_contesto().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 1:
							if ( iter->get_gaikokugo().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 2:
							if ( iter->get_kotoba().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 3:
							if ( iter->get_yomikata().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 4:
							if ( iter->get_contesto().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
					}
				}
				if ( _match )
				{
					Gtk::TreeModel::iterator iterTree = _paroleListStore->append();
					Gtk::TreeModel::Row row = *iterTree;
					row[_paroleListColumns->parola] = iter->get_gaikokugo();
					row[_paroleListColumns->kotoba] = iter->get_kotoba();
					row[_paroleListColumns->yomikata] = iter->get_yomikata();
					row[_paroleListColumns->tipo] = iter->get_tipo_name ();
					row[_paroleListColumns->contesto] = iter->get_contesto();
				}
			}
		}
		iter++;
	}
}

list<Parola>::iterator Controller::
get_parola_iterator ( Gtk::TreeModel::Row _row )
{
	list<Parola>::iterator _it;
	Parola _temp;
	_temp.set_kotoba ( _row[_paroleListColumns->kotoba] );
	_temp.set_yomikata ( _row[_paroleListColumns->yomikata] );
	_temp.set_gaikokugo ( _row[_paroleListColumns->parola] );
	_temp.set_tipo_from_name ( _row[_paroleListColumns->tipo] );
	_it = find (_parole->begin(), _parole->end(), _temp);
	return _it;
}

void Controller::
parole_tree_remove_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _paroleListModel = _paroleDictList->get_model ();
	get_tree_row_ref ( _sel, _paroleListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _paroleListModel->get_iter ( _srIter->get_path () );
		list<Parola>::iterator _it = get_parola_iterator ( *_itRem );
		if ( _it != _parole->end() )
		{
			_parole->erase ( _it );
			_paroleListStore->erase ( _itRem );
		}
		else
			cerr << "Errore: non trovo la Parola" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( Glib::ustring::compose( "Una parola eliminata, %1 parole nel dizionario.", Glib::ustring::format( _parole->size() ) ) );
	else
		_messaggio.append ( Glib::ustring::compose( "%1 parole eliminate, %2 parole nel dizionario.", Glib::ustring::format( _sel.size() ), Glib::ustring::format( _parole->size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
on_parole_tree_double_clicked ( GdkEventButton *event )
{
	if ( event->type == GDK_2BUTTON_PRESS )
	{
		vector<Gtk::TreePath> _selected = _paroleDictSelection->get_selected_rows ();
		int nrSel = _paroleDictSelection->count_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _paroleListModel = _paroleDictList->get_model ();
		if ( nrSel > 0 )
		{
			vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
			Gtk::TreeModel::iterator _iterView = _paroleListModel->get_iter ( *_iter );
			Gtk::TreeModel::Row _row = *_iterView;
			_newTipoCombobox->set_active ( Parola::get_tipo_index_from_name ( _row[_paroleListColumns->tipo] ) );
			_newParContesto->set_text ( _row[_paroleListColumns->contesto] );
			if ( nrSel > 1 )
			{
				_newKotoba->set_text ( "selezione multipla" );
				_newKotoba->set_sensitive ( false );
				_newYomikata->set_text ( "selezione multipla" );
				_newYomikata->set_sensitive ( false );
				_newParTraduzione->set_text ( "selezione multipla" );
				_newParTraduzione->set_sensitive ( false );
			}
			else
			{
				_newKotoba->set_text ( _row[_paroleListColumns->kotoba] );
				_newKotoba->set_sensitive ( true );
				_newYomikata->set_text ( _row[_paroleListColumns->yomikata] );
				_newYomikata->set_sensitive ( true );
				_newParTraduzione->set_text ( _row[_paroleListColumns->parola] );
				_newParTraduzione->set_sensitive ( true );
			}
			_addParWin->present ();
		}
	}
}

Voce* Controller::
populate_parola_info ( Gtk::TreeModel::Row _row )
{
	Glib::ustring _kotobaTxt = _row[_paroleListColumns->kotoba];
	Glib::ustring _yomikataTxt = _row[_paroleListColumns->yomikata];
	Glib::ustring _traduzioneTxt = _row[_paroleListColumns->parola];
	Glib::ustring _tipoTxt = _row[_paroleListColumns->tipo];
	_infoItemProValLabel1->set_text ( _kotobaTxt );
	_infoItemProValLabel2->set_text ( _yomikataTxt );
	_infoItemProValLabel3->set_text ( _traduzioneTxt );
	_infoItemProValLabel4->set_text ( _tipoTxt );
	_infoItemProValLabel5->set_text ( _row[_paroleListColumns->contesto] );
	list<Parola>::iterator iter = get_parola_iterator ( _row );
	Voce *vox = 0;
	if ( iter != _parole->end() )
	{
		list<Glib::ustring> _knjList;
		if ( iter->get_kanji_list ( _knjList ) )
		{
			_infoItemKanjiListStore->clear();
			list<Glib::ustring>::iterator _iter = _knjList.begin();
			list<Glib::ustring>::iterator _end = _knjList.end();
			while ( _iter != _end )
			{
				list<Kanji>::iterator _iterKnj = _kanji->begin();
				Kanji _temp;
				_temp.set_kanji ( *_iter );
				Gtk::TreeModel::iterator iterKnjList = _infoItemKanjiListStore->append();
				Gtk::TreeModel::Row row = *iterKnjList;
				row[_kanjiListColumns->kanji] = _temp.get_kanji();
				_iterKnj = find ( _kanji->begin(), _kanji->end(), _temp );
				if ( _iterKnj != _kanji->end() )
				{
					row[_kanjiListColumns->tratti] = _iterKnj->get_tratti();
					row[_kanjiListColumns->radicale] = _iterKnj->get_radicale();
				}
				_iter++;
			}
		}
		list<Glib::ustring> _exaList;
		iter->get_forme_list ( _exaList );
		list<Glib::ustring>::iterator _iterExaList = _exaList.begin();
		list<Glib::ustring>::iterator _exaListEnd = _exaList.end();
		_infoItemEsempiListStore->clear();
		while ( _iterExaList != _exaListEnd )
		{
			StringaInEsempio _comp ( *_iterExaList );
			list<Esempio>::iterator _itExmp = _esempi->begin();
			list<Esempio>::iterator _startSearch = _itExmp;
			list<Esempio>::iterator _endSearch = _esempi->end();
			while ( _startSearch != _endSearch )
			{
				_itExmp = find_if ( _startSearch, _endSearch, _comp );
				_startSearch = _itExmp;
				if ( _itExmp != _esempi->end() )
				{
					Gtk::TreeModel::iterator iterExmpList = _infoItemEsempiListStore->append();
					Gtk::TreeModel::Row row2 = *iterExmpList;
					row2[_esempiListColumns->frase] = _itExmp->get_bun();
					_startSearch++;
				}
			}
			_iterExaList++;
		}
		vox = &(*iter);
	}
	else
		cerr << "Errore: non trovo la parola" << endl;
	return vox;
}

void Controller::
parole_tree_reset_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _paroleListModel = _paroleDictList->get_model ();
	get_tree_row_ref ( _sel, _paroleListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _paroleListModel->get_iter ( _srIter->get_path () );
		list<Parola>::iterator _it = get_parola_iterator ( *_itRem );
		if ( _it != _parole->end() )
			_it->reset_stats ();
		else
			cerr << "Errore: non trovo la Parola" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Azzerate le statistiche di una parola." );
	else
		_messaggio.append ( Glib::ustring::compose( "Azzerate le statistiche di %1 parole.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
export_parole_to_xml ( ofstream *xmlstr, const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _paroleListModel = _paroleDictList->get_model ();
	get_tree_row_ref ( _sel, _paroleListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _paroleListModel->get_iter ( _srIter->get_path () );
		list<Parola>::iterator _it = get_parola_iterator ( *_itRem );
		if ( _it != _parole->end() )
			*xmlstr << _it->get_xml_string ( sys_language );
		else
			cerr << "Errore: non trovo la Parola" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemDiskId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Esportata una parola." );
	else
		_messaggio.append ( Glib::ustring::compose( "Esportate %1 parole.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemDiskId );
}

void Controller::
on_add_parola_confirm_button_clicked ( void )
{
	bool result = true;
	int nrSel = _paroleDictSelection->count_selected_rows ();
	if ( nrSel == 0 )
	{
		Glib::ustring _kotoba = _newKotoba->get_text ();
		Glib::ustring _yomikata = _newYomikata->get_text ();
		Glib::ustring _parola = _newParTraduzione->get_text ();
		int _tipo = _newTipoCombobox->get_active_row_number () + 1;
		Glib::ustring _contesto = _newParContesto->get_text ();
		if ( _parola != "" && _kotoba != "" )
		{
			Parola _par;
			_par.set_kotoba ( _kotoba );
			_par.set_yomikata ( _yomikata );
			_par.set_gaikokugo ( _parola );
			_par.set_tipo ( _tipo );
			_par.set_contesto ( _contesto );
			list<Parola>::iterator _found = find ( _parole->begin(), _parole->end(), _par );
			if ( _found != _parole->end() )
			{
				Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "La stessa parola è già presente nel dizionario, vuoi sostituirla con questa?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
				int res_id = _alertDialog->run();
				delete _alertDialog;
				if ( res_id == Gtk::RESPONSE_YES )
					_found->set_contesto ( _contesto ); // gli altri attributi sono uguali
			}
			else
			{
				_parole->push_back ( _par );
				on_items_list_selection_changed ();
			}
		}
		else
		{
			Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addParWin, "I campi <b>言葉</b> e <b>Traduzione</b> non possono essere vuoti!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
			int res_id = _alertDialog->run();
			delete _alertDialog;
			if ( res_id == Gtk::RESPONSE_OK )
				result = false;
		}
	}
	else
	{
		vector<Gtk::TreePath> _selected = _paroleDictSelection->get_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _paroleListModel = _paroleDictList->get_model ();
		vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
		vector<Gtk::TreePath>::const_iterator _end = _selected.end ();
		list<Parola>::iterator _iterParole;
		list<Parola>::iterator _endParole = _parole->end();
		unsigned char _tipo = _newTipoCombobox->get_active_row_number () + 1;
		Glib::ustring _contesto = _newParContesto->get_text ();
		while ( _iter != _end )
		{
			Gtk::TreeModel::iterator _iterView = _paroleListModel->get_iter ( *_iter );
			_iterParole = get_parola_iterator ( *_iterView );
			if ( _iterParole != _endParole )
			{
				if ( nrSel == 1 )
				{
					Glib::ustring _editKotoba = _newKotoba->get_text ();
					Glib::ustring _editTraduzione = _newParTraduzione->get_text ();
					if ( _editKotoba.raw() != "" && _editTraduzione != "" )
					{
						_iterParole->set_kotoba ( _editKotoba );
						_iterParole->set_gaikokugo ( _editTraduzione );
					}
					else
					{
						Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addParWin, "I campi <b>言葉</b> e <b>Traduzione</b> non possono essere vuoti!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
						int res_id = _alertDialog->run();
						delete _alertDialog;
						if ( res_id == Gtk::RESPONSE_OK )
						result = false;
					}
					if ( result )
						_iterParole->set_yomikata ( _newYomikata->get_text () );
				}
				if ( result )
				{
					_iterParole->set_tipo ( _tipo );
					_iterParole->set_contesto ( _contesto );
				}
			}
			else
				cerr << "Errore: non ho trovato la Parola da modificare!" << endl;
			_iter++;
		}
	}
	if ( result )
	{
		_shouldSave = true;
		_saveToolButton->set_sensitive ( true );
		_saveMenuItem->set_sensitive ( true );
		load_parole_in_tree_view ();
		_addParWin->hide ();
	}
}

void Controller::
load_kanji_in_tree_view ( bool filtro )
{
	unsigned char filtroTratti = filtro ? _srchItemComboBox1->get_active_row_number () : 0;
	Glib::ustring filtroString = filtro ? _srchItemEntry2->get_text () : Glib::ustring ( "" );
	bool filtroStringValido = ( filtroString != Glib::ustring ( "" ) );
	unsigned char filtroCampo = filtro ? _srchItemComboBox3->get_active_row_number () : 0;
	Glib::ustring quickString = filtro ? _quickSearchEntry->get_text () : Glib::ustring ( "" );
	bool quickStringValido = ( quickString != Glib::ustring ( "" ) );
	unsigned char quickSearchCampo = 0;
	if ( quickStringValido )
	{
		if ( _quickSearchKanjiMenuItem2->get_active () )
			quickSearchCampo = 1;
		if ( _quickSearchKanjiMenuItem3->get_active () )
			quickSearchCampo = 2;
		if ( _quickSearchKanjiMenuItem4->get_active () )
			quickSearchCampo = 3;
		if ( _quickSearchKanjiMenuItem5->get_active () )
			quickSearchCampo = 4;
		if ( _quickSearchKanjiMenuItem6->get_active () )
			quickSearchCampo = 5;
		if ( _quickSearchKanjiMenuItem7->get_active () )
			quickSearchCampo = 6;
	}
	_kanjiListStore->clear();
	list<Kanji>::iterator iter = _kanji->begin();
	list<Kanji>::iterator iterEnd = _kanji->end();
	while (iter != iterEnd)
	{
		bool _match = true;
		if ( filtroTratti > 0 )
		{
			if ( iter->get_tratti() != filtroTratti )
				_match = false;
		}
		if ( _match )
		{
			if ( filtroStringValido )
			{
				switch ( filtroCampo )
				{
					case 0:
						if ( iter->get_kanji().find( filtroString ) == Glib::ustring::npos && iter->get_radicale().find( filtroString ) == Glib::ustring::npos && !iter->contiene_onyomi( filtroString ) && !iter->contiene_kunyomi( filtroString ) && iter->get_significato().find( filtroString ) == Glib::ustring::npos && iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 1:
						if ( iter->get_kanji().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 2:
						if ( iter->get_radicale().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 3:
						if ( !iter->contiene_onyomi( filtroString ) )
							_match = false;
						break;
					case 4:
						if ( !iter->contiene_kunyomi( filtroString ) )
							_match = false;
						break;
					case 5:
						if ( iter->get_significato().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 6:
						if ( iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
							_match = false;
						break;
				}
			}
			if ( _match )
			{
				if ( quickStringValido )
				{
					switch ( quickSearchCampo )
					{
						case 0:
							if ( iter->get_kanji().find( quickString ) == Glib::ustring::npos && iter->get_radicale().find( quickString ) == Glib::ustring::npos && !iter->contiene_onyomi( quickString ) && !iter->contiene_kunyomi( quickString ) && iter->get_significato().find( quickString ) == Glib::ustring::npos && iter->get_contesto().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 1:
							if ( iter->get_kanji().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 2:
							if ( iter->get_radicale().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 3:
							if ( !iter->contiene_onyomi( quickString ) )
								_match = false;
							break;
						case 4:
							if ( !iter->contiene_kunyomi( quickString ) )
								_match = false;
							break;
						case 5:
							if ( iter->get_significato().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
						case 6:
							if ( iter->get_contesto().find( quickString ) == Glib::ustring::npos )
								_match = false;
							break;
					}
				}
				if ( _match )
				{
					Gtk::TreeModel::iterator iterTree = _kanjiListStore->append();
					Gtk::TreeModel::Row row = *iterTree;
					row[_kanjiListColumns->kanji] = iter->get_kanji();
					row[_kanjiListColumns->tratti] = iter->get_tratti();
					row[_kanjiListColumns->radicale] = iter->get_radicale();
					row[_kanjiListColumns->trattiRadicale] = iter->get_tratti_radicale();
					row[_kanjiListColumns->kunyomi] = iter->get_kunyomi();
					row[_kanjiListColumns->onyomi] = iter->get_onyomi();
					row[_kanjiListColumns->significato] = iter->get_significato();
					row[_kanjiListColumns->contesto] = iter->get_contesto ();
				}
			}
		}
	iter++;
	}
}

list<Kanji>::iterator Controller::
get_kanji_iterator ( Gtk::TreeModel::Row _row )
{
	list<Kanji>::iterator _it;
	Kanji _temp = Kanji ( _row[_kanjiListColumns->kanji] );
	_it = find ( _kanji->begin(), _kanji->end(), _temp );
	return _it;
}

void Controller::
kanji_tree_remove_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _kanjiListModel = _kanjiDictList->get_model ();
	get_tree_row_ref ( _sel, _kanjiListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _kanjiListModel->get_iter ( _srIter->get_path () );
		list<Kanji>::iterator _it = get_kanji_iterator ( *_itRem );
		if ( _it != _kanji->end() )
		{
			_kanji->erase ( _it );
			_kanjiListStore->erase ( _itRem );
		}
		else
			cerr << "Errore: non trovo il Kanji" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( Glib::ustring::compose( "Un kanji eliminato, %1 kanji nel dizionario.", Glib::ustring::format( _kanji->size() ) ) );
	else
		_messaggio.append ( Glib::ustring::compose( "%1 kanji eliminati, %2 kanji nel dizionario.", Glib::ustring::format( _sel.size() ), Glib::ustring::format( _kanji->size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
on_kanji_tree_double_clicked ( GdkEventButton *event )
{
	if ( event->type == GDK_2BUTTON_PRESS )
	{
		vector<Gtk::TreePath> _selected = _kanjiDictSelection->get_selected_rows ();
		int nrSel = _kanjiDictSelection->count_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _kanjiListModel = _kanjiDictList->get_model ();
		if ( nrSel > 0 )
		{
			vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
			Gtk::TreeModel::iterator _iterView = _kanjiListModel->get_iter ( *_iter );
			Gtk::TreeModel::Row _row = *_iterView;
			_newRadicale->set_text ( _row[_kanjiListColumns->radicale] );
			stringstream trattiRadStr;
			trattiRadStr << static_cast<int>( _row[_kanjiListColumns->trattiRadicale] );
			_newTrattiRadicale->set_text ( trattiRadStr.str() );
			_newKnjContesto->set_text ( _row[_kanjiListColumns->contesto] );
			if ( nrSel > 1 )
			{
				_newKanji->set_text ( "selezione multipla" );
				_newKanji->set_sensitive ( false );
				_newTratti->set_text ( "selezione multipla" );
				_newTratti->set_sensitive ( false );
				_newKunyomi->set_text ( "selezione multipla" );
				_newKunyomi->set_sensitive ( false );
				_newOnyomi->set_text ( "selezione multipla" );
				_newOnyomi->set_sensitive ( false );
				_newSignificato->set_text ( "selezione multipla" );
				_newSignificato->set_sensitive ( false );
			}
			else
			{
				_newKanji->set_text ( _row[_kanjiListColumns->kanji] );
				_newKanji->set_sensitive ( true );
				stringstream trattiStr;
				trattiStr << static_cast<int>( _row[_kanjiListColumns->tratti] );
				_newTratti->set_text ( trattiStr.str() );
				_newTratti->set_sensitive ( true );
				_newKunyomi->set_text ( _row[_kanjiListColumns->kunyomi] );
				_newKunyomi->set_sensitive ( true );
				_newOnyomi->set_text ( _row[_kanjiListColumns->onyomi] );
				_newOnyomi->set_sensitive ( true );
				_newSignificato->set_text ( _row[_kanjiListColumns->significato] );
				_newSignificato->set_sensitive ( true );
			}
			_addKnjWin->present ();
		}
	}
}

Voce* Controller::
populate_kanji_info ( Gtk::TreeModel::Row _row )
{
	Voce *vox = 0;
	list<Kanji>::iterator iter = get_kanji_iterator ( _row );
	if ( iter != _kanji->end() )
	{
		vox = &(*iter);
		_infoItemProValLabel1->set_text ( iter->get_kanji () );
		_infoItemProValLabel2->set_text ( Glib::ustring::format ( static_cast<int>( iter->get_tratti () ) ) );
		_infoItemProValLabel3->set_text ( iter->get_radicale() );
		_infoItemProValLabel4->set_text ( Glib::ustring::format ( static_cast<int>( iter->get_tratti_radicale () ) ) );
		_infoItemProValLabel5->set_text ( iter->get_kunyomi () );
		_infoItemProValLabel6->set_text ( iter->get_onyomi () );
		_infoItemProValLabel7->set_text ( iter->get_significato () );
		_infoItemProValLabel8->set_text ( iter->get_contesto () );
		_infoItemParoleListStore->clear();
		StringaInParola _comp ( iter->get_kanji() );
		list<Parola>::iterator _iterParFound = _parole->begin();
		list<Parola>::iterator _startSearch = _iterParFound;
		list<Parola>::iterator _endSearch = _parole->end();
		while ( _iterParFound != _endSearch )
		{
			_iterParFound = find_if ( _startSearch, _endSearch, _comp );
			_startSearch = _iterParFound;
			if ( _startSearch != _endSearch )
			{
				Gtk::TreeModel::iterator iterParList = _infoItemParoleListStore->append();
				Gtk::TreeModel::Row row = *iterParList;
				row[_paroleListColumns->parola] = _iterParFound->get_gaikokugo();
				row[_paroleListColumns->kotoba] = _iterParFound->get_kotoba();
				row[_paroleListColumns->yomikata] = _iterParFound->get_yomikata();
				_startSearch++;
			}
		}
		_infoItemEsempiListStore->clear ();
		StringaInEsempio _comp2 ( iter->get_kanji() );
		list<Esempio>::iterator _iterExaFound = _esempi->begin();
		list<Esempio>::iterator _startSearch2 = _iterExaFound;
		list<Esempio>::iterator _endSearch2 = _esempi->end();
		while ( _iterExaFound != _endSearch2 )
		{
			_iterExaFound = find_if ( _startSearch2, _endSearch2, _comp2 );
			_startSearch2 = _iterExaFound;
			if ( _startSearch2 != _endSearch2 )
			{
				Gtk::TreeModel::iterator iterExaList = _infoItemEsempiListStore->append();
				Gtk::TreeModel::Row row2 = *iterExaList;
				row2[_esempiListColumns->frase] = _iterExaFound->get_bun();
				_startSearch2++;
			}
		}
	}
	else
		cerr << "Errore: non trovo il kanji" << endl;
	return vox;
}

void Controller::
kanji_tree_reset_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _kanjiListModel = _kanjiDictList->get_model ();
	get_tree_row_ref ( _sel, _kanjiListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _kanjiListModel->get_iter ( _srIter->get_path () );
		list<Kanji>::iterator _it = get_kanji_iterator ( *_itRem );
		if ( _it != _kanji->end() )
			_it->reset_stats ();
		else
			cerr << "Errore: non trovo il Kanji" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Azzerate le statistiche di un kanji." );
	else
		_messaggio.append ( Glib::ustring::compose( "Azzerate le statistiche di %1 kanji.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
export_kanji_to_xml ( ofstream *xmlstr, const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _kanjiListModel = _kanjiDictList->get_model ();
	get_tree_row_ref ( _sel, _kanjiListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _kanjiListModel->get_iter ( _srIter->get_path () );
		list<Kanji>::iterator _it = get_kanji_iterator ( *_itRem );
		if ( _it != _kanji->end() )
			*xmlstr << _it->get_xml_string ( sys_language );
		else
			cerr << "Errore: non trovo il Kanji" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemDiskId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Esportato un kanji." );
	else
		_messaggio.append ( Glib::ustring::compose( "Esportati %1 kanji.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemDiskId );
}

void Controller::
on_add_kanji_confirm_button_clicked ( void )
{
	bool result = true;
	int nrSel = _kanjiDictSelection->count_selected_rows ();
	if ( nrSel == 0 )
	{
		Glib::ustring _kanjiStr = _newKanji->get_text ();
		Glib::ustring _radicale = _newRadicale->get_text ();
		unsigned char _tratti = atoi ( _newTratti->get_text ().c_str() );
		unsigned char _trattiRad = atoi ( _newTrattiRadicale->get_text ().c_str() );
		Glib::ustring _kunyomi = _newKunyomi->get_text ();
		Glib::ustring _onyomi = _newOnyomi->get_text ();
		Glib::ustring _significato = _newSignificato->get_text ();
		Glib::ustring _contesto = _newKnjContesto->get_text ();
		if ( _kanjiStr != "" )
		{
			if ( Kanji::is_kanji ( _kanjiStr ) )
			{
				Kanji knj = Kanji ( _kanjiStr );
				list<Kanji>::iterator _found = find ( _kanji->begin(), _kanji->end(), knj );
				if ( _found != _kanji->end() )
				{
					Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "Lo stesso kanji è già presente nel database, vuoi sostituirlo con questo?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
					int res_id = _alertDialog->run();
					delete _alertDialog;
					if ( res_id == Gtk::RESPONSE_YES )
					{
						_found->set_radicale ( _radicale );
						_found->set_tratti ( _tratti );
						_found->set_tratti_radicale ( _trattiRad );
						_found->set_kunyomi ( _kunyomi );
						_found->set_onyomi ( _onyomi );
						_found->set_significato ( _significato );
						_found->set_contesto ( _contesto );
					}
					else
						result = false;
				}
				else
				{
					knj.set_tratti ( _tratti );
					knj.set_radicale ( _radicale );
					knj.set_tratti_radicale ( _trattiRad );
					knj.set_kunyomi ( _kunyomi );
					knj.set_onyomi ( _onyomi );
					knj.set_significato ( _significato );
					knj.set_contesto ( _contesto );
					_kanji->push_back ( knj );
					on_items_list_selection_changed ();
				}
			}
			else
			{
				Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addKnjWin, "Il campo <b>漢字</b> deve contenere un kanji!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
				int res_id = _alertDialog->run();
				delete _alertDialog;
				if ( res_id == Gtk::RESPONSE_OK )
					result = false;
			}
		}
		else
		{
			Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addKnjWin, "Il campo <b>漢字</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
			int res_id = _alertDialog->run();
			delete _alertDialog;
			if ( res_id == Gtk::RESPONSE_OK )
				result = false;
		}
	}
	else
	{
		vector<Gtk::TreePath> _selected = _kanjiDictSelection->get_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _kanjiListModel = _kanjiDictList->get_model ();
		vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
		vector<Gtk::TreePath>::const_iterator _end = _selected.end ();
		list<Kanji>::iterator _iterKanji;
		list<Kanji>::iterator _endKanji = _kanji->end();
		Glib::ustring _radicale = _newRadicale->get_text ();
		unsigned char _trattiRadicale = atoi ( _newTrattiRadicale->get_text ().c_str () );
		Glib::ustring _contesto = _newKnjContesto->get_text ();
		while ( _iter != _end )
		{
			Gtk::TreeModel::iterator _iterView = _kanjiListModel->get_iter ( *_iter );
			_iterKanji = get_kanji_iterator ( *_iterView );
			if ( _iterKanji != _endKanji )
			{
				if ( nrSel == 1 )
				{
					Glib::ustring _editKanji = _newKanji->get_text ();
					if ( _editKanji.raw() != "" )
					{
						if ( Kanji::is_kanji ( _editKanji ) )
							_iterKanji->set_kanji ( _editKanji );
						else
						{
							Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addKnjWin, "Il campo <b>漢字</b> deve contenere un kanji!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
							int res_id = _alertDialog->run();
							delete _alertDialog;
							if ( res_id == Gtk::RESPONSE_OK )
								result = false;
						}
					}
					else
					{
						Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addKnjWin, "Il campo <b>漢字</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
						int res_id = _alertDialog->run();
						delete _alertDialog;
						if ( res_id == Gtk::RESPONSE_OK )
							result = false;
					}
					if ( result )
					{
						_iterKanji->set_tratti ( _newTratti->get_text ().c_str () );
						Glib::ustring _kunyomi = _newKunyomi->get_text ();
						Glib::ustring _onyomi = _newOnyomi->get_text ();
						_iterKanji->set_kunyomi ( _kunyomi );
						_iterKanji->set_onyomi ( _onyomi );
						_iterKanji->set_significato ( _newSignificato->get_text () );
					}
				}
				if ( result )
				{
					_iterKanji->set_radicale ( _radicale );
					_iterKanji->set_tratti_radicale ( _trattiRadicale );
					_iterKanji->set_contesto ( _contesto );
				}
			}
			_iter++;
		}
	}
	if ( result )
	{
		_shouldSave = true;
		_saveToolButton->set_sensitive ( true );
		_saveMenuItem->set_sensitive ( true );
		load_kanji_in_tree_view ();
		_addKnjWin->hide ();
	}
}

void Controller::
load_esempi_in_tree_view ( bool filtro )
{
	Glib::ustring filtroString = filtro ? _srchItemEntry2->get_text () : Glib::ustring ( "" );
	bool filtroStringValido = ( filtroString != Glib::ustring ( "" ) );
	unsigned char filtroCampo = filtro ? _srchItemComboBox3->get_active_row_number () : 0;
	Glib::ustring quickString = filtro ? _quickSearchEntry->get_text () : Glib::ustring ( "" );
	bool quickStringValido = ( quickString != Glib::ustring ( "" ) );
	unsigned char quickSearchCampo = 0;
	if ( quickStringValido )
	{
		if ( _quickSearchEsempiMenuItem2->get_active () )
			quickSearchCampo = 1;
		if ( _quickSearchEsempiMenuItem3->get_active () )
			quickSearchCampo = 2;
		if ( _quickSearchEsempiMenuItem4->get_active () )
			quickSearchCampo = 3;
	}
	_esempiListStore->clear();
	list<Esempio>::iterator iter = _esempi->begin();
	list<Esempio>::iterator iterEnd = _esempi->end();
	while (iter != iterEnd)
	{
		bool _match = true;
		if ( filtroStringValido )
		{
			switch ( filtroCampo )
			{
				case 0:
					if ( iter->get_bun().find( filtroString ) == Glib::ustring::npos && iter->get_gaikokugo().find( filtroString ) == Glib::ustring::npos && iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
						_match = false;
					break;
				case 1:
					if ( iter->get_bun().find( filtroString ) == Glib::ustring::npos )
						_match = false;
					break;
				case 2:
					if ( iter->get_gaikokugo().find( filtroString ) == Glib::ustring::npos )
						_match = false;
					break;
				case 3:
					if ( iter->get_contesto().find( filtroString ) == Glib::ustring::npos )
						_match = false;
					break;
			}
		}
		if ( _match )
		{
			if ( quickStringValido )
			{
				switch ( quickSearchCampo )
				{
					case 0:
						if ( iter->get_bun().find( quickString ) == Glib::ustring::npos && iter->get_gaikokugo().find( quickString ) == Glib::ustring::npos && iter->get_contesto().find( quickString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 1:
						if ( iter->get_bun().find( quickString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 2:
						if ( iter->get_gaikokugo().find( quickString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 3:
						if ( iter->get_contesto().find( quickString ) == Glib::ustring::npos )
							_match = false;
						break;
				}
			}
			if ( _match )
			{
				Gtk::TreeModel::iterator iterTree = _esempiListStore->append();
				Gtk::TreeModel::Row row = *iterTree;
				row[_esempiListColumns->frase] = iter->get_bun();
				row[_esempiListColumns->traduzione] = iter->get_gaikokugo();
				row[_esempiListColumns->contesto] = iter->get_contesto();
			}
		}
		iter++;
	}
}

list<Esempio>::iterator Controller::
get_esempio_iterator ( Gtk::TreeModel::Row _row )
{
	list<Esempio>::iterator _it;
	Esempio _temp = Esempio ( _row[_esempiListColumns->frase] );
	_it = find (_esempi->begin(), _esempi->end(), _temp);
	return _it;
}

void Controller::
esempi_tree_remove_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _esempiListModel = _esempiDictList->get_model ();
	get_tree_row_ref ( _sel, _esempiListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _esempiListModel->get_iter ( _srIter->get_path () );
		list<Esempio>::iterator _it = get_esempio_iterator ( *_itRem );
		if ( _it != _esempi->end() )
		{
			_esempi->erase ( _it );
			_esempiListStore->erase ( _itRem );
		}
		else
			cerr << "Errore: non trovo l'Esempio" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( Glib::ustring::compose( "Un esempio eliminato, %1 esempi nel dizionario.", Glib::ustring::format( _esempi->size() ) ) );
	else
		_messaggio.append ( Glib::ustring::compose( "%1 esempi eliminati, %2 esempi nel dizionario.", Glib::ustring::format( _sel.size() ), Glib::ustring::format( _esempi->size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
on_esempi_tree_double_clicked ( GdkEventButton *event )
{
	if ( event->type == GDK_2BUTTON_PRESS )
	{
		vector<Gtk::TreePath> _selected = _esempiDictSelection->get_selected_rows ();
		int nrSel = _esempiDictSelection->count_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _esempiListModel = _esempiDictList->get_model ();
		if ( nrSel > 0 )
		{
			vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
			Gtk::TreeModel::iterator _iterView = _esempiListModel->get_iter ( *_iter );
			Gtk::TreeModel::Row _row = *_iterView;
			_newExaContesto->set_text ( _row[_esempiListColumns->contesto] );
			if ( nrSel > 1 )
			{
				_newFrase->set_text ( "selezione multipla" );
				_newFrase->set_sensitive ( false );
				_newExaTraduzione->set_text ( "selezione multipla" );
				_newExaTraduzione->set_sensitive ( false );
			}
			else
			{
				_newFrase->set_text ( _row[_esempiListColumns->frase] );
				_newFrase->set_sensitive ( true );
				_newExaTraduzione->set_text ( _row[_esempiListColumns->traduzione] );
				_newExaTraduzione->set_sensitive ( true );
			}
			_addExaWin->present ();
		}
	}
}

void Controller::
populate_esempio_info ( Gtk::TreeModel::Row _row )
{
	Glib::ustring _frase = _row[_esempiListColumns->frase];
	_infoItemProValLabel1->set_text ( _frase );
	_infoItemProValLabel2->set_text ( _row[_esempiListColumns->traduzione] );
	_infoItemProValLabel3->set_text ( _row[_esempiListColumns->contesto] );
	list<Parola>::iterator _itParStart = _parole->begin();
	list<Parola>::iterator _itParFound = _itParStart;
	list<Parola>::iterator _itParEnd = _parole->end();
	StringaContieneParola _comp ( _frase );
	_infoItemParoleListStore->clear();
	while ( _itParStart != _itParEnd )
	{
		_itParFound = find_if ( _itParStart, _itParEnd, _comp );
		_itParStart = _itParFound;
		if ( _itParFound != _itParEnd )
		{
			Gtk::TreeModel::iterator iterParList = _infoItemParoleListStore->append();
			Gtk::TreeModel::Row row = *iterParList;
			row[_paroleListColumns->parola] = _itParFound->get_gaikokugo();
			row[_paroleListColumns->kotoba] = _itParFound->get_kotoba();
			row[_paroleListColumns->yomikata] = _itParFound->get_yomikata();
			_itParStart++;
		}
	}

	list<Kanji>::iterator _itKnjStart = _kanji->begin();
	list<Kanji>::iterator _itKnjFound = _itKnjStart;
	list<Kanji>::iterator _itKnjEnd = _kanji->end();
	StringaContieneKanji _comp2 ( _frase );
	_infoItemKanjiListStore->clear();
	while ( _itKnjStart != _itKnjEnd )
	{
		_itKnjFound = find_if ( _itKnjStart, _itKnjEnd, _comp2 );
		_itKnjStart = _itKnjFound;
		if ( _itKnjFound != _itKnjEnd )
		{
			Gtk::TreeModel::iterator iterKnjList = _infoItemKanjiListStore->append();
			Gtk::TreeModel::Row row2 = *iterKnjList;
			row2[_kanjiListColumns->kanji] = _itKnjFound->get_kanji();
			row2[_kanjiListColumns->tratti] = _itKnjFound->get_tratti();
			row2[_kanjiListColumns->radicale] = _itKnjFound->get_radicale();
			_itKnjStart++;
		}
	}
}

void Controller::
export_esempi_to_xml ( ofstream *xmlstr, const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _esempiListModel = _esempiDictList->get_model ();
	get_tree_row_ref ( _sel, _esempiListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _esempiListModel->get_iter ( _srIter->get_path () );
		list<Esempio>::iterator _it = get_esempio_iterator ( *_itRem );
		if ( _it != _esempi->end() )
			*xmlstr << _it->get_xml_string ( sys_language );
		else
			cerr << "Errore: non trovo l'Esempio" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemDiskId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Esportato un esempio." );
	else
		_messaggio.append ( Glib::ustring::compose( "Esportati %1 esempi.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemDiskId );
}

void Controller::
on_add_esempio_confirm_button_clicked ( void )
{
	bool result = true;
	int nrSel = _esempiDictSelection->count_selected_rows ();
	if ( nrSel == 0 )
	{
		Glib::ustring _frase = _newFrase->get_text ();
		Glib::ustring _traduzione = _newExaTraduzione->get_text ();
		Glib::ustring _contesto = _newExaContesto->get_text ();
		if ( _frase != "" )
		{
			Esempio _exmp = Esempio ( _frase );
			_exmp.set_gaikokugo ( _traduzione );
			_exmp.set_contesto ( _contesto );
			list<Esempio>::iterator _found = find ( _esempi->begin(), _esempi->end(), _exmp );
			if ( _found != _esempi->end() )
			{
				Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, "La stessa frase è già presente negli esempi, vuoi sostituirla con questa?", false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
				int res_id = _alertDialog->run();
				delete _alertDialog;
				if ( res_id == Gtk::RESPONSE_YES )
				{
					_found->set_gaikokugo ( _traduzione );
					_found->set_contesto ( _contesto ); // gli altri attributi sono uguali
				}
			}
			else
			{
				_esempi->push_back ( _exmp );
				on_items_list_selection_changed ();
			}
		}
		else
		{
			Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addExaWin, "Il campo <b>Frase</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
			int res_id = _alertDialog->run();
			delete _alertDialog;
			if ( res_id == Gtk::RESPONSE_OK )
				result = false;
		}
	}
	else
	{
		vector<Gtk::TreePath> _selected = _esempiDictSelection->get_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _esempiListModel = _esempiDictList->get_model ();
		vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
		vector<Gtk::TreePath>::const_iterator _end = _selected.end ();
		list<Esempio>::iterator _iterEsempi;
		list<Esempio>::iterator _endEsempi = _esempi->end();
		Glib::ustring _contesto = _newExaContesto->get_text ();
		while ( _iter != _end )
		{
			Gtk::TreeModel::iterator _iterView = _esempiListModel->get_iter ( *_iter );
			_iterEsempi = get_esempio_iterator ( *_iterView );
			if ( _iterEsempi != _endEsempi )
			{
				if ( nrSel == 1 )
				{
					Glib::ustring _editFrase = _newFrase->get_text ();
					if ( _editFrase != "" )
						_iterEsempi->set_bun ( _editFrase );
					else
					{
						Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addExaWin, "Il campo <b>Frase</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
						int res_id = _alertDialog->run();
						delete _alertDialog;
						if ( res_id == Gtk::RESPONSE_OK )
							result = false;
					}
					if ( result )
						_iterEsempi->set_gaikokugo ( _newExaTraduzione->get_text () );
				}
				if ( result )
					_iterEsempi->set_contesto ( _contesto );
			}
			else
				cerr << "Errore: non ho trovato l'Esempio da modificare!" << endl;
			_iter++;
		}
	}
	if ( result )
	{
		_shouldSave = true;
		_saveToolButton->set_sensitive ( true );
		_saveMenuItem->set_sensitive ( true );
		load_esempi_in_tree_view ();
		_addExaWin->hide ();
	}
}

void Controller::
load_lezioni_in_tree_view ( bool filtro )
{
	Glib::ustring filtroString = filtro ? _srchItemEntry2->get_text () : Glib::ustring ( "" );
	bool filtroStringValido = ( filtroString != Glib::ustring ( "" ) );
	unsigned char filtroCampo = filtro ? _srchItemComboBox3->get_active_row_number () : 0;
	Glib::ustring quickString = filtro ? _quickSearchEntry->get_text () : Glib::ustring ( "" );
	bool quickStringValido = ( quickString != Glib::ustring ( "" ) );
	unsigned char quickSearchCampo = 0;
	if ( quickStringValido )
	{
		if ( _quickSearchLezioniMenuItem2->get_active () )
			quickSearchCampo = 1;
		if ( _quickSearchLezioniMenuItem3->get_active () )
			quickSearchCampo = 2;
		if ( _quickSearchLezioniMenuItem4->get_active () )
			quickSearchCampo = 3;
		if ( _quickSearchLezioniMenuItem5->get_active () )
			quickSearchCampo = 4;
	}
	_lezioniListStore->clear();
	_addToLectioListStore->clear();
	Gtk::TreeModel::iterator firstIter = _addToLectioListStore->append();
	Gtk::TreeModel::Row firstRow = *firstIter;
	Glib::ustring _nuovaLezione ( "Nuova lezione" );
	firstRow[_buttonPopUpColumn->columnCell] = _nuovaLezione;
	list<Lezione>::iterator iter = _lezioni->begin();
	list<Lezione>::iterator iterEnd = _lezioni->end();
	while (iter != iterEnd)
	{
		bool _match = true;
		if ( filtroStringValido )
		{
			switch ( filtroCampo )
			{
				case 0:
					if ( iter->get_nome().find( filtroString ) == Glib::ustring::npos && !iter->contiene_parola ( filtroString, false ) && !iter->contiene_kanji ( filtroString ) && !iter->contiene_esempio ( filtroString, false ) )
						_match = false;
					break;
				case 1:
					if ( iter->get_nome().find( filtroString ) == Glib::ustring::npos )
						_match = false;
					break;
				case 2:
					if ( !iter->contiene_parola ( filtroString, false ) )
						_match = false;
					break;
				case 3:
					if ( !iter->contiene_kanji ( filtroString ) )
						_match = false;
					break;
				case 4:
					if ( !iter->contiene_esempio ( filtroString, false ) )
						_match = false;
					break;
			}
		}
		if ( _match )
		{
			if ( quickStringValido )
			{
				switch ( quickSearchCampo )
				{
					case 0:
						if ( iter->get_nome().find( quickString ) == Glib::ustring::npos && !iter->contiene_parola ( quickString, false ) && !iter->contiene_kanji ( quickString ) && !iter->contiene_esempio ( quickString, false ) )
							_match = false;
						break;
					case 1:
						if ( iter->get_nome().find( quickString ) == Glib::ustring::npos )
							_match = false;
						break;
					case 2:
						if ( !iter->contiene_parola ( quickString, false ) )
							_match = false;
						break;
					case 3:
						if ( !iter->contiene_kanji ( quickString ) )
							_match = false;
						break;
					case 4:
						if ( !iter->contiene_esempio ( quickString, false ) )
							_match = false;
						break;
				}
			}
			if ( _match )
			{
				Gtk::TreeModel::iterator iterTree = _lezioniListStore->append();
				Gtk::TreeModel::Row row = *iterTree;
				row[_lezioniListColumns->nome] = iter->get_nome();
				row[_lezioniListColumns->parole] = iter->count_parole();
				row[_lezioniListColumns->kanji] = iter->count_kanji();
				row[_lezioniListColumns->esempi] = iter->count_esempi();
				Gtk::TreeModel::iterator iter2 = _addToLectioListStore->append();
				Gtk::TreeModel::Row row2 = *iter2;
				row2[_buttonPopUpColumn->columnCell] = iter->get_nome();
			}
		}
		iter++;
	}
	_addToLectioCombobox->set_active ( 0 );
}

list<Lezione>::iterator Controller::
get_lezione_iterator ( Gtk::TreeModel::Row _row )
{
	list<Lezione>::iterator _it;
	Lezione _temp ( _row[_lezioniListColumns->nome] );
	_it = find (_lezioni->begin(), _lezioni->end(), _temp);
	return _it;
}

void Controller::
lezioni_tree_remove_selected_rows ( const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _lezioniListModel = _lezioniDictList->get_model ();
	get_tree_row_ref ( _sel, _lezioniListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _lezioniListModel->get_iter ( _srIter->get_path () );
		list<Lezione>::iterator _it = get_lezione_iterator ( *_itRem );
		if ( _it != _lezioni->end() )
		{
			_lezioni->erase ( _it );
			_lezioniListStore->erase ( _itRem );
		}
		else
			cerr << "Errore: non trovo la lezione" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemSelId );
	if ( _sel.size() == 1 )
		_messaggio.append ( Glib::ustring::compose( "Una lezione eliminata, %1 lezioni nel database.", Glib::ustring::format( _lezioni->size() ) ) );
	else
		_messaggio.append ( Glib::ustring::compose( "%1 lezioni eliminate, %2 lezioni nel database.", Glib::ustring::format( _sel.size() ), Glib::ustring::format( _lezioni->size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemSelId );
}

void Controller::
on_lezioni_tree_double_clicked ( GdkEventButton *event )
{
	if ( event->type == GDK_2BUTTON_PRESS )
	{
		vector<Gtk::TreePath> _selected = _lezioniDictSelection->get_selected_rows ();
		int nrSel = _lezioniDictSelection->count_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _lezioniListModel = _lezioniDictList->get_model ();
		if ( nrSel > 0 )
		{
			vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
			Gtk::TreeModel::iterator _iterView = _lezioniListModel->get_iter ( *_iter );
			Gtk::TreeModel::Row _row = *_iterView;
			Glib::ustring _nomeStr = _row[_lezioniListColumns->nome];
			_addLezEntry->set_text ( _nomeStr );
			list<Lezione>::iterator _iterLez = get_lezione_iterator ( _row );
			if ( _iterLez != _lezioni->end() )
			{
				load_parole_della_lezione_in_tree_view( *_iterLez, _addLezParListStore );
				load_kanji_della_lezione_in_tree_view ( *_iterLez, _addLezKnjListStore );
				load_esempi_della_lezione_in_tree_view ( *_iterLez );
			}
			else
				cerr << "Errore: non trovo la lezione!" << endl;
			_addLezWin->present ();
		}
	}
}

void Controller::
populate_lezione_info ( Gtk::TreeModel::Row _row )
{
	Glib::ustring _nome = _row[_lezioniListColumns->nome];
	_infoItemProValLabel1->set_text ( _nome );
	list<Lezione>::iterator _itLectio = get_lezione_iterator ( _row );
	if ( _itLectio != _lezioni->end() )
	{
		load_parole_della_lezione_in_tree_view( *_itLectio, _infoItemParoleListStore );
		load_kanji_della_lezione_in_tree_view ( *_itLectio, _infoItemKanjiListStore );
	}
	else
		cerr << "Non trovo la lezione!" << endl;
}

void Controller::
export_lezioni_to_xml ( ofstream *xmlstr, const vector<Gtk::TreePath> &_sel )
{
	Glib::ustring _messaggio;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _lezioniListModel = _lezioniDictList->get_model ();
	get_tree_row_ref ( _sel, _lezioniListModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _lezioniListModel->get_iter ( _srIter->get_path () );
		list<Lezione>::iterator _it = get_lezione_iterator ( *_itRem );
		if ( _it != _lezioni->end() )
		{
			*xmlstr << _it->get_xml_string ();
			if ( _it->count_parole () > 0 )
			{
				list<Parola>::iterator iterList = _parole->begin();
				list<Parola>::iterator iterListEnd = _parole->end();
				while (iterList != iterListEnd)
				{
					if ( _it->contiene_parola ( iterList->get_kotoba() ) )
						*xmlstr << iterList->get_xml_string ( sys_language );
					iterList++;
				}
			}
			if ( _it->count_kanji () > 0 )
			{
				list<Kanji>::iterator iterList = _kanji->begin();
				list<Kanji>::iterator iterListEnd = _kanji->end();
				while (iterList != iterListEnd)
				{
					if ( _it->contiene_kanji ( iterList->get_kanji() ) )
						*xmlstr << iterList->get_xml_string ( sys_language );
					iterList++;
				}
			}
			if ( _it->count_esempi () > 0 )
			{
				list<Esempio>::iterator iterList = _esempi->begin();
				list<Esempio>::iterator iterListEnd = _esempi->end();
				while (iterList != iterListEnd)
				{
					if ( _it->contiene_esempio ( iterList->get_bun() ) )
						*xmlstr << iterList->get_xml_string ( sys_language );
					iterList++;
				}
			}
		}
		else
			cerr << "Errore: non trovo la lezione" << endl;
		_srIter++;
	}
	_mainStatus->pop ( _stsItemDiskId );
	if ( _sel.size() == 1 )
		_messaggio.append ( "Esportata una lezione." );
	else
		_messaggio.append ( Glib::ustring::compose( "Esportate %1 lezioni.", Glib::ustring::format( _sel.size() ) ) );
	_mainStatus->push ( _messaggio, _stsItemDiskId );
}

void Controller::
on_add_lectio_confirm_button_clicked ( void )
{
	bool result = true;
	int nrSel = _lezioniDictSelection->count_selected_rows ();
	Glib::ustring _nome = _addLezEntry->get_text ();
	if ( nrSel == 0 )
	{
		if ( _nome.raw() != "" )
		{
			int _nrs = 1;
			Glib::ustring _nuovoNome ( _nome );
			Lezione _lectio = Lezione ( "" );
			list<Lezione>::iterator _found;
			do
			{
				_lectio.set_nome ( _nuovoNome );
				_found = find ( _lezioni->begin(), _lezioni->end(), _lectio );
				if ( _found != _lezioni->end() )
					_nuovoNome.assign ( _nome + Glib::ustring::format ( _nrs++ ) );
			}
			while ( _found != _lezioni->end() );
			_lezioni->push_back ( _lectio );
			on_items_list_selection_changed ();
		}
		else
		{
			Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addLezWin, "Il campo <b>Nome</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
			int res_id = _alertDialog->run();
			delete _alertDialog;
			if ( res_id == Gtk::RESPONSE_OK )
				result = false;
		}
	}
	else
	{
		vector<Gtk::TreePath> _selected = _lezioniDictSelection->get_selected_rows ();
		Glib::RefPtr<Gtk::TreeModel> _lezioniListModel = _lezioniDictList->get_model ();
		vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
		vector<Gtk::TreePath>::const_iterator _end = _selected.end ();
		list<Lezione>::iterator _iterLezioni;
		list<Lezione>::iterator _endLezioni = _lezioni->end();
		Glib::ustring _nome = _addLezEntry->get_text ();
		if ( _iter != _end )
		{
			Gtk::TreeModel::iterator _iterView = _lezioniListModel->get_iter ( *_iter );
			_iterLezioni = get_lezione_iterator ( *_iterView );
			if ( _iterLezioni != _endLezioni )
			{
				if ( _nome.raw() != "" )
					_iterLezioni->set_nome ( _nome );
				else
				{
					Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_addLezWin, "Il campo <b>Nome</b> non può essere vuoto!", true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
					int res_id = _alertDialog->run();
					delete _alertDialog;
					if ( res_id == Gtk::RESPONSE_OK )
						result = false;
				}
				if ( result )
				{
					list<Glib::ustring> _listaStringhe;
					Gtk::TreeModel::const_iterator _iterParList = _addLezParListStore->children().begin();
					Gtk::TreeModel::const_iterator _endParList = _addLezParListStore->children().end();
					while ( _iterParList != _endParList )
					{
						Gtk::TreeModel::Row _rowParList = *_iterParList;
						Glib::ustring _parStr = _rowParList[_paroleListColumns->kotoba];
						if ( _parStr.raw() == "" )
							_parStr.assign ( _rowParList[_paroleListColumns->yomikata] );
						_listaStringhe.push_back ( _parStr );
						_iterParList++;
					}
					if ( _listaStringhe.size() != _iterLezioni->count_parole () )
						_iterLezioni->set_parole ( _listaStringhe );
					_listaStringhe.clear ();
					Gtk::TreeModel::const_iterator _iterKnjList = _addLezKnjListStore->children().begin();
					Gtk::TreeModel::const_iterator _endKnjList = _addLezKnjListStore->children().end();
					while ( _iterKnjList != _endKnjList )
					{
						Gtk::TreeModel::Row _rowKnjList = *_iterKnjList;
						Glib::ustring _knjStr = _rowKnjList[_kanjiListColumns->kanji];
						_listaStringhe.push_back ( _knjStr );
						_iterKnjList++;
					}
					if ( _listaStringhe.size() != _iterLezioni->count_kanji () )
						_iterLezioni->set_kanji ( _listaStringhe );
					_listaStringhe.clear ();
					Gtk::TreeModel::const_iterator _iterExaList = _addLezExaListStore->children().begin();
					Gtk::TreeModel::const_iterator _endExaList = _addLezExaListStore->children().end();
					while ( _iterExaList != _endExaList )
					{
						Gtk::TreeModel::Row _rowExaList = *_iterExaList;
						Glib::ustring _exaStr = _rowExaList[_esempiListColumns->frase];
						_listaStringhe.push_back ( _exaStr );
						_iterExaList++;
					}
					if ( _listaStringhe.size() != _iterLezioni->count_esempi () )
						_iterLezioni->set_esempi ( _listaStringhe );
				}
			}
			else
				cerr << "Errore: non ho trovato la lezione da modificare!" << endl;
		}
	}
	if ( result )
	{
		_addLezWin->hide ();
		_shouldSave = true;
		_saveToolButton->set_sensitive ( true );
		_saveMenuItem->set_sensitive ( true );
		load_lezioni_in_tree_view ();
	}
}

void Controller::
load_parole_della_lezione_in_tree_view ( const Lezione &lectio, Glib::RefPtr<Gtk::ListStore> _listStore )
{
	_listStore->clear();
	list<Parola>::iterator iterList = _parole->begin();
	list<Parola>::iterator iterListEnd = _parole->end();
	while (iterList != iterListEnd)
	{
		bool _match = false;
		if ( lectio.contiene_parola ( iterList->get_kotoba() ) )
			_match = true;
		if ( _match )
		{
			Gtk::TreeModel::iterator iter = _listStore->append();
			Gtk::TreeModel::Row row = *iter;
			row[_paroleListColumns->parola] = iterList->get_gaikokugo();
			row[_paroleListColumns->kotoba] = iterList->get_kotoba();
			row[_paroleListColumns->yomikata] = iterList->get_yomikata();
		}	
		iterList++;
	}
}

void Controller::
load_kanji_della_lezione_in_tree_view ( const Lezione &lectio, Glib::RefPtr<Gtk::ListStore> _listStore )
{
	_listStore->clear();
	list<Kanji>::iterator iterList = _kanji->begin();
	list<Kanji>::iterator iterListEnd = _kanji->end();
	while (iterList != iterListEnd)
	{
		bool _match = false;
		Glib::ustring _knjStr = iterList->get_kanji();
		if ( lectio.contiene_kanji ( _knjStr ) )
			_match = true;
		if ( _match )
		{
			Gtk::TreeModel::iterator iter = _listStore->append();
			Gtk::TreeModel::Row row = *iter;
			row[_kanjiListColumns->kanji] = iterList->get_kanji();
			row[_kanjiListColumns->tratti] = iterList->get_tratti();
			row[_kanjiListColumns->radicale] = iterList->get_radicale();
		}	
		iterList++;
	}
}

void Controller::
load_esempi_della_lezione_in_tree_view ( const Lezione &lectio )
{
	_addLezExaListStore->clear();
	list<Esempio>::iterator iterList = _esempi->begin();
	list<Esempio>::iterator iterListEnd = _esempi->end();
	while (iterList != iterListEnd)
	{
		bool _match = false;
		Glib::ustring _exaStr = iterList->get_bun();
		if ( lectio.contiene_esempio ( _exaStr ) )
			_match = true;
		if ( _match )
		{
			Gtk::TreeModel::iterator iter = _addLezExaListStore->append();
			Gtk::TreeModel::Row row = *iter;
			row[_esempiListColumns->frase] = iterList->get_bun();
			row[_esempiListColumns->traduzione] = iterList->get_gaikokugo();
		}	
		iterList++;
	}
}

void Controller::
on_lectio_contenuto_tree_button_dx_clicked ( GdkEventButton *event )
{
	if ( event->type == GDK_BUTTON_PRESS && event->button == 3 )
	{
		_lectioItemPopUpMenu->popup (event->button, event->time);
	}
}

void Controller::
on_menu_lectio_remove_item_selected ( void )
{
	vector<Gtk::TreePath> _selected;
	vector<Gtk::TreeRowReference> _selRef;
	Glib::RefPtr<Gtk::TreeModel> _listModel;
	int nrPage = _addLezNotebook->get_current_page ();
	switch ( nrPage )
	{
		case 0:
			_selected = _lezioniParListSelection->get_selected_rows ();
			_listModel = _addLezParList->get_model ();
			break;
		case 1:
			_selected = _lezioniKnjListSelection->get_selected_rows ();
			_listModel = _addLezKnjList->get_model ();
			break;
		case 2:
			_selected = _lezioniExaListSelection->get_selected_rows ();
			_listModel = _addLezExaList->get_model ();
			break;
	}
	get_tree_row_ref ( _selected, _listModel, _selRef );
	vector<Gtk::TreeRowReference>::iterator _srIter = _selRef.begin();
	vector<Gtk::TreeRowReference>::iterator _srEnd = _selRef.end();
	while ( _srIter != _srEnd )
	{
		Gtk::TreeModel::iterator _itRem = _listModel->get_iter ( _srIter->get_path () );
		Gtk::TreeModel::Row _row = *_itRem;
		switch ( nrPage )
		{
			case 0:
				_addLezParListStore->erase ( _itRem );
				break;
			case 1:
				_addLezKnjListStore->erase ( _itRem );
				break;
			case 2:
				_addLezExaListStore->erase ( _itRem );
				break;
		}
		_srIter++;
	}
}

void Controller::
on_add_to_lectio_confirm_button_clicked ( void )
{
	Lezione *_lectio = 0;
	list<Lezione>::iterator _iterLectio;
	if ( _addToLectioCombobox->get_active_row_number () == 0 )
	{
		Glib::ustring _nomeNuova = _addToLectioEntry->get_text();
		if ( _nomeNuova.raw() == "" )
			_nomeNuova.assign ( "Nuova lezione senza nome" );
		Lezione _nuova ( _nomeNuova );
		short nl = 1;
		do
		{
			_iterLectio = find ( _lezioni->begin(), _lezioni->end(), _nuova );
			if ( _iterLectio != _lezioni->end() )
				_nuova.set_nome ( _nomeNuova + Glib::ustring::format ( nl++ ) );
		} while ( _iterLectio != _lezioni->end() );
		_lezioni->push_back ( _nuova );
		_lectio = &(_lezioni->back());
	}
	else
	{
		Gtk::TreeModel::iterator _lectioSel = _addToLectioCombobox->get_active ();
		Glib::RefPtr<Gtk::TreeModel> _lezioniListModel = _addToLectioCombobox->get_model ();
		Gtk::TreeModel::Row _rowLectio = *_lectioSel;
		Glib::ustring nomeLectio = _rowLectio[_buttonPopUpColumn->columnCell];
		Lezione _temp ( nomeLectio );
		_iterLectio = find ( _lezioni->begin(), _lezioni->end(), _temp );
		if ( _iterLectio == _lezioni->end() )
			cerr << "non trovo la lezione!" << endl;
		else
			_lectio = &(*_iterLectio);
	}
	
	vector<Gtk::TreePath> _selected;
	Glib::RefPtr<Gtk::TreeModel> _listModel;
	switch ( _mainPage )
	{
		case 0:
			_selected = _paroleDictSelection->get_selected_rows ();
			_listModel = _paroleDictList->get_model ();
			break;
		case 1:
			_selected = _kanjiDictSelection->get_selected_rows ();
			_listModel = _kanjiDictList->get_model ();
			break;
		case 3:
			_selected = _esempiDictSelection->get_selected_rows ();
			_listModel = _esempiDictList->get_model ();
			break;
	}
	vector<Gtk::TreePath>::const_iterator _iter = _selected.begin ();
	vector<Gtk::TreePath>::const_iterator _end = _selected.end();
	while ( _iter != _end )
	{
		Gtk::TreeModel::iterator _iterView = _listModel->get_iter ( *_iter );
		Gtk::TreeModel::Row _row = *_iterView;
		Glib::ustring _rife ( "" );
		switch ( _mainPage )
		{
			case 0:
				if ( _row[_paroleListColumns->kotoba] != _rife )
					_rife.assign ( _row[_paroleListColumns->kotoba] );
				else
					_rife.assign ( _row[_paroleListColumns->yomikata] );
				_lectio->push_parola ( _rife );
				break;
			case 1:
				_rife.assign ( _row[_kanjiListColumns->kanji] );
				_lectio->push_kanji ( _rife );
				break;
			case 3:
				_rife.assign ( _row[_esempiListColumns->frase] );
				_lectio->push_esempio ( _rife );
				break;
		}
		_iter++;
	}
	_shouldSave = true;
	_saveToolButton->set_sensitive ( true );
	_saveMenuItem->set_sensitive ( true );
	load_lezioni_in_tree_view ();
	_addToLezioneWin->hide();
}

void Controller::
on_add_to_lectio_selection_changed ( void )
{
	if ( _addToLectioCombobox->get_active_row_number () > 0 )
	{
		if ( _addToLectioEntry->get_sensitive () )
			_addToLectioEntry->set_sensitive ( false );
	}
	else
	{
		if ( !_addToLectioEntry->get_sensitive () )
			_addToLectioEntry->set_sensitive ( true );
	}
}

void Controller::
on_signal_items_changed ( void )
{
	_shouldSave = true;
	_saveToolButton->set_sensitive ( true );
	_saveMenuItem->set_sensitive ( true );
}

void Controller::
on_signal_attribute_found ( const Glib::ustring lang )
{
	if ( lang != sys_language )
		cout << "language different from system" << endl;
}

void Controller::
on_signal_parola_loaded ( const Parola &verbum )
{
	int res_id = 0;
	list<Parola>::iterator _found = find ( _parole->begin(), _parole->end(), verbum );
	if ( _found != _parole->end() )
	{
		Glib::ustring messaggio = Glib::ustring ( "La parola \"" ) + verbum.get_kotoba() + Glib::ustring ( "\" è già presente nel dizionario, vuoi sostituirla con quella importata?" );
		Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, messaggio, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
		res_id = _alertDialog->run();
		delete _alertDialog;
		if ( res_id == Gtk::RESPONSE_YES )
			_parole->erase ( _found );
	}
	if ( res_id != Gtk::RESPONSE_NO )
	{
		_parole->push_back ( verbum );
		_paroleCaricate++;
	}
}

void Controller::
on_signal_kanji_loaded ( const Kanji &signum )
{
	int res_id = 0;
	list<Kanji>::iterator _found = find ( _kanji->begin(), _kanji->end(), signum );
	if ( _found != _kanji->end() )
	{
		Glib::ustring messaggio = Glib::ustring ( "Il Kanji \"" ) + signum.get_kanji() + Glib::ustring ( "\" è già presente nel dizionario, vuoi sostituirlo con quello importato?" );
		Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, messaggio, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
		res_id = _alertDialog->run();
		delete _alertDialog;
		if ( res_id == Gtk::RESPONSE_YES )
			_kanji->erase ( _found );
	}
	if ( res_id != Gtk::RESPONSE_NO )
	{
		_kanji->push_back ( signum );
		_kanjiCaricati++;
	}
}

void Controller::
on_signal_esempio_loaded ( const Esempio &exemplum )
{
	int res_id = 0;
	list<Esempio>::iterator _found = find ( _esempi->begin(), _esempi->end(), exemplum );
	if ( _found != _esempi->end() )
	{
		Glib::ustring messaggio = Glib::ustring ( "L'esempio \"" ) + exemplum.get_bun() + Glib::ustring ( "\" è già presente nel dizionario, vuoi sostituirlo con quello importato?" );
		Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, messaggio, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
		res_id = _alertDialog->run();
		delete _alertDialog;
		if ( res_id == Gtk::RESPONSE_YES )
			_esempi->erase ( _found );
	}
	if ( res_id != Gtk::RESPONSE_NO )
	{
		_esempi->push_back ( exemplum );
		_esempiCaricati++;
	}
}

void Controller::
on_signal_lezione_loaded ( const Lezione &lectio )
{
	int res_id = 0;
	list<Lezione>::iterator _found = find ( _lezioni->begin(), _lezioni->end(), lectio );
	if ( _found != _lezioni->end() )
	{
		Glib::ustring messaggio = Glib::ustring ( "La lezione \"" ) + lectio.get_nome() + Glib::ustring ( "\" è già presente nel dizionario, vuoi sostituirla con quella importata?" );
		Gtk::MessageDialog *_alertDialog = new Gtk::MessageDialog ( *_mainWin, messaggio, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
		res_id = _alertDialog->run();
		delete _alertDialog;
		if ( res_id == Gtk::RESPONSE_YES )
			_lezioni->erase ( _found );
	}
	if ( res_id != Gtk::RESPONSE_NO )
	{
		_lezioni->push_back ( lectio );
		_lezioniCaricate++;
	}
}

void Controller::
on_signal_import_end ( void )
{
	Glib::ustring messaggio = "Caricato: ";
	if ( _paroleCaricate > 0 )
	{
		load_parole_in_tree_view ( true );
		messaggio.append ( Glib::ustring::compose ( "%1 parole", Glib::ustring::format ( _paroleCaricate ) ) );
	}
	if ( _kanjiCaricati > 0 )
	{
		load_kanji_in_tree_view ( true );
		if ( messaggio[ messaggio.size() - 1 ] != ' ' )
			messaggio.append ( ", " );
		messaggio.append ( Glib::ustring::compose ( "%1 kanji", Glib::ustring::format ( _kanjiCaricati ) ) );
	}
	if ( _esempiCaricati > 0 )
	{
		load_esempi_in_tree_view ( true );
		if ( messaggio[ messaggio.size() - 1 ] != ' ' )
			messaggio.append ( ", " );
		messaggio.append ( Glib::ustring::compose ( "%1 esempi", Glib::ustring::format ( _esempiCaricati ) ) );
	}
	if ( _lezioniCaricate > 0 )
	{
		load_lezioni_in_tree_view ( true );
		if ( messaggio[ messaggio.size() - 1 ] != ' ' )
			messaggio.append ( ", " );
		messaggio.append ( Glib::ustring::compose ( "%1 lezioni", Glib::ustring::format ( _lezioniCaricate ) ) );
	}
	_mainStatus->pop ( _stsItemDiskId );
	_mainStatus->push ( messaggio, _stsItemDiskId );
	
	if ( _startingApp == STATUS_RUNNING )
	{
		if ( _paroleCaricate + _kanjiCaricati + _esempiCaricati + _lezioniCaricate > 0 )
			_shouldSave = true;
	}
	else
		_startingApp = STATUS_RUNNING;
}
